澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

用jdbc连接数据库并简单执行SQL语句,JDBC的连接

2019-06-16 作者:数据库网络   |   浏览(168)

  那只是笔者自个儿的小说博客~,用于不时回想知识,或者存在有的指鹿为马,如有错误,应接指正~

一、eclipse的使用

1......

一:版本一.这种存在四个主题素材便是每实行贰遍操作都会创立叁遍Connection链接和且释放三回链接

正文内容

首先对此JDBC连接MySQL,要打听主旨的架构

1、修改注释内容

Driver接口:数据库驱动程序的接口,全部具体数据库商家要求的驱动程序要求贯彻次接口。

1:创设pojo对象(O奥迪Q5映射,贰个pojo类对应一张数据库表)

 

图片 1图片 2

 1 package com.yinfu.dao;
 2  
 3  public class Employee {
 4  
 5      private int id;
 6      private String name;
 7      private String password;
 8      public int getId() {
 9          return id;
10      }
11      public void setId(int id) {
12          this.id = id;
13      }
14      public String getName() {
15          return name;
16      }
17      public void setName(String name) {
18          this.name = name;
19      }
20      public String getPassword() {
21          return password;
22      }
23      public void setPassword(String password) {
24          this.password = password;
25      }
26      @Override
27      public String toString() {
28          return "Employee [id="   id   ", name="   name   ", password="   password   "]";
29      }
30      public Employee(int id, String name, String password) {
31          super();
32          this.id = id;
33          this.name = name;
34          this.password = password;
35      }
36      public Employee() {
37          super();
38      }
39  }

pojo对象

1.怎么是JDBC以及为何要运用JDBC

图片 3

选择window---->>preferences

Connection connect(String url,Properties info)用于获取数据库连接

2:创造数据库连接用的数据文件,用于外界读取数据(properties文件):

2.JDBC核心API的讲解

画的可比烂,大概正是如此的组织

图片 4

2.....

 1 driver=com.mysql.jdbc.Driver 2 jdbcUrl=jdbc:mysql://localhost:3306/test 3 user=root 4 password=song12345 

3.使用JDBC核心API进行CRUD操作

接下来看一下有血有肉落到实处的 代码:;

慎选Java---->>codestyle---->>code template---->>comments,然后双击types,修改里面包车型大巴情节就可以!

|-Connection接口:与具象的数据库的接连对象。

3:创设数据库连接和关闭连接的工具类(被重复使用的点子能够写在工具类中):

  1 package com.yinfu.utils;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.sql.Connection;
  6 import java.sql.DriverManager;
  7 import java.sql.PreparedStatement;
  8 import java.sql.ResultSet;
  9 import java.sql.SQLException;
 10 import java.util.Properties;
 11 /**
 12  * JDBC的工具类,封装了jdbc的一些方法
 13  * @author lusong
 14  *
 15  */
 16 public class JDBCUtils {
 17 
 18     //关闭jdbc的链接
 19     /**
 20      * 关闭statement和connection
 21      * @param ps
 22      * @param conn
 23      */
 24     public static void release(PreparedStatement ps, Connection conn){
 25         try {
 26             if(ps != null){
 27                 ps.close();
 28             }
 29         } catch (SQLException e) {
 30             e.printStackTrace();
 31         }finally{
 32             try {
 33                 if(conn != null){
 34                     conn.close();
 35                 }
 36             } catch (SQLException e) {
 37                 e.printStackTrace();
 38             }
 39         }
 40     }
 41     public static void release(ResultSet result,PreparedStatement ps, Connection conn){
 42         try {
 43             if(result != null){
 44                 result.close();
 45             }
 46         } catch (SQLException e1) {
 47             e1.printStackTrace();
 48         }finally{
 49             try {
 50                 if(ps != null){
 51                     ps.close();
 52                 }
 53             } catch (SQLException e) {
 54                 e.printStackTrace();
 55             }finally{
 56                 try {
 57                     if(conn != null){
 58                         conn.close();
 59                     }
 60                 } catch (SQLException e) {
 61                     e.printStackTrace();
 62                 }
 63             }
 64         }
 65         
 66     }
 67     
 68     //获取jdbc的链接
 69     /**
 70      * 用于创建jdbc链接的工具类对象
 71      * @return
 72      */
 73     public static Connection getConnetions() {
 74         Connection conn = null;
 75         String driverClass = null;
 76         String jdbcUrl = null;
 77         String user = null;
 78         String password = null;
 79         
 80         try {
 81             //读取配置文件中的配置
 82             InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
 83             Properties properties = new Properties();
 84             properties.load(is);
 85             driverClass = properties.getProperty("driver");
 86             jdbcUrl = properties.getProperty("jdbcUrl");
 87             user = properties.getProperty("user");
 88             password = properties.getProperty("password");
 89             //注册驱动程序
 90             Class.forName(driverClass);
 91             //实际应该这样写(由于对应的应用程序中有一个对应的静态代码块,自动回将驱动的类对象进行驱动加载)
 92             //DriverManager.registerDriver((Driver) Class.forName(driverClass).newInstance());
 93             
 94             conn = DriverManager.getConnection(jdbcUrl,user,password);
 95             
 96         } catch (IOException e) {
 97             // TODO Auto-generated catch block
 98             e.printStackTrace();
 99         }catch (SQLException e) {
100             // TODO Auto-generated catch block
101             e.printStackTrace();
102         }catch (ClassNotFoundException e) {
103             // TODO Auto-generated catch block
104             e.printStackTrace();
105         }
106         return conn;
107     }
108 }

4.JDBC的工具类的抽取与校对

public class DBUtil {
 private String user = "root";
 private String password = "root";
 private String url = "jdbc:mysql://localhost:3306/mydb6";
 private static DBUtil dbUtil;
 Connection connection = null;

 // 单例:构造方法私有化
 private DBUtil() {

 }

 public synchronized static DBUtil getInstance() {
  if (dbUtil == null) {
   dbUtil = new DBUtil();
  }
  return dbUtil;
 }

 /**
  * 创建数据库连接
  */
 public Connection getConnection() {
  if (connection == null) {
   try {
    // 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 获取连接
    connection = DriverManager.getConnection(url, user, password);
   } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  return connection;
 }
}

 

Statement         createStatement()创立一个静态sql语句对象

4:用Junit测试达成的JDBC完毕数据库的增加和删除改查操作:

 1 package com.yinfu.test;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.sql.Connection;
 6 import java.sql.DriverManager;
 7 import java.sql.PreparedStatement;
 8 import java.sql.ResultSet;
 9 import java.sql.SQLException;
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Properties;
13 
14 import org.junit.Test;
15 
16 import com.yinfu.dao.Employee;
17 import com.yinfu.utils.JDBCUtils;
18 
19 public class JDBCTest {
20 
21     @Test
22     public void testUpdate(){
23         //曾
24         String sql = "insert into employee (Id,Name,Password) values (1,'wangba',131)";
25         //删
26         //String sql = "delete from employee where id = 1";
27         //改
28         //String sql = "update employee set name = 'fuck' where id = 2";
29         //查
30         String sqlQuery = "select * from employee";
31         update(sql);
32         testQueryObject(sqlQuery);
33     }
34     
35     public void testQueryObject(String sql){
36         Employee employee = null;
37         List<Employee> list = new ArrayList();
38         Connection conn = null;
39         PreparedStatement ps = null;
40         ResultSet result = null;
41         try {
42             //创建连接
43             conn = JDBCUtils.getConnetions();
44             //创建prepareStatement对象,用于执行SQL
45             ps = conn.prepareStatement(sql);
46             //获取查询结果集
47             result = ps.executeQuery();
48             while(result.next()){
49                 employee = new Employee(result.getInt(1),result.getString(2),result.getString(3));
50                 list.add(employee);
51             }
52             System.out.println(list);
53         } catch (Exception e) {
54             e.printStackTrace();
55         }finally{
56             JDBCUtils.release(result, ps, conn);
57         }
58     }
59     
60     public void update(String sql){
61         Connection conn = null;
62         PreparedStatement ps = null;
63         try {
64             //创建数据库连接
65             conn = JDBCUtils.getConnetions();
66             //创建执行SQL的prepareStatement对象
67             ps = conn.prepareStatement(sql);
68             //用于增删改操作
69             int result = ps.executeUpdate();
70             System.out.println(result);
71         } catch (Exception e) {
72             System.out.println("出现异常1=" e.toString());
73         }finally{
74             JDBCUtils.release(ps, conn);
75         }
76 
77         
78     }
79 }

Statement 和PrepareStatement的区别:

率先是施行SQL的主意:

statement: 

  Class.forName(jdbcDriver);

  Connection conn = DriverManager.getConnection(jdbcUrl,userName,password);

  String sql = "insert into employee () values ('','','')"

  Statement statement = conn.createStatement();

  statement.executeUpdate(sql);

  当中的SQL语句中若有要动态输入的数量时,须求用字符串拼接SQL,难以保险轻巧出错。

prepareStatement:

  Class.forName(jdbcDriver);

  Connection conn = DriverManager.getConnection(jdbcUrl,userName,password);

  String sql = "insert into employee () values ('','','')"

  PrepareStatement ps = conn.prepareStatement(sql);

  statement.executeUpdate();

  当中的SQL语句中如若有动态输入的多寡时,能够用占位'?'符来顶替:

  String sql = "insert into employee () values (?,?,?)";

  然后用prepareStatement接口中的方法来动态赋值:

  ps.setXXX(int paramIndex ,Object value);//参数含义:占位符对应的索引值,该索引值对应的参数值;

5.JDBC的SQL注入漏洞剖判与化解方案

  下面那几个是通过单例情势  建立了DBUtil那样四个类。通过这些类能够怎么呢?能够兑现----数据库的连年!

图片 5

PreparedStatement        prepareStatement(String sql)创制预编写翻译的sql语句对象

 2:(利用反射工具类)进级版查询:利用反射和JDBC元数据编写通用的查询单条记录格局(ResultSetMetaData是结果集的元数据对象):

6.应用JDBC的PreparedStatement预编写翻译对象举办CRUD操作(注重)

准确,Connection接口的效应正是接二连三数据库-
与特定数据库的连日(会话)。在连年内外文中施行 SQL 语句并再次回到结果。

2、修改Eclipse里面的快速键

(存在sql注入漏洞的bug)

1:创设反射工具类:

图片 6图片 7

  1 package com.yinfu.utils;
  2 
  3 import java.lang.reflect.Field;
  4 import java.lang.reflect.InvocationTargetException;
  5 import java.lang.reflect.Method;
  6 import java.lang.reflect.Modifier;
  7 import java.lang.reflect.ParameterizedType;
  8 import java.lang.reflect.Type;
  9 
 10 /**
 11  * 反射的 Utils 函数集合 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
 12  * 
 13  * @author Administrator
 14  *
 15  */
 16 public class ReflectionUtils {
 17 
 18     /**
 19      * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型 如: public EmployeeDao extends
 20      * BaseDao<Employee, String>
 21      * 
 22      * @param clazz
 23      * @param index
 24      * @return
 25      */
 26     @SuppressWarnings("unchecked")
 27     public static Class getSuperClassGenricType(Class clazz, int index) {
 28         Type genType = clazz.getGenericSuperclass();
 29 
 30         if (!(genType instanceof ParameterizedType)) {
 31             return Object.class;
 32         }
 33 
 34         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
 35 
 36         if (index >= params.length || index < 0) {
 37             return Object.class;
 38         }
 39 
 40         if (!(params[index] instanceof Class)) {
 41             return Object.class;
 42         }
 43 
 44         return (Class) params[index];
 45     }
 46 
 47     /**
 48      * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型 如: public EmployeeDao extends
 49      * BaseDao<Employee, String>
 50      * 
 51      * @param <T>
 52      * @param clazz
 53      * @return
 54      */
 55     @SuppressWarnings("unchecked")
 56     public static <T> Class<T> getSuperGenericType(Class clazz) {
 57         return getSuperClassGenricType(clazz, 0);
 58     }
 59 
 60     /**
 61      * 循环向上转型, 获取对象的 DeclaredMethod
 62      * 
 63      * @param object
 64      * @param methodName
 65      * @param parameterTypes
 66      * @return
 67      */
 68     public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {
 69 
 70         for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
 71                 .getSuperclass()) {
 72             try {
 73                 // superClass.getMethod(methodName, parameterTypes);
 74                 return superClass.getDeclaredMethod(methodName, parameterTypes);
 75             } catch (NoSuchMethodException e) {
 76                 // Method 不在当前类定义, 继续向上转型
 77             }
 78             // ..
 79         }
 80 
 81         return null;
 82     }
 83 
 84     /**
 85      * 使 filed 变为可访问
 86      * 
 87      * @param field
 88      */
 89     public static void makeAccessible(Field field) {
 90         if (!Modifier.isPublic(field.getModifiers())) {
 91             field.setAccessible(true);
 92         }
 93     }
 94 
 95     /**
 96      * 循环向上转型, 获取对象的 DeclaredField
 97      * 
 98      * @param object
 99      * @param filedName
100      * @return
101      */
102     public static Field getDeclaredField(Object object, String filedName) {
103 
104         for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
105                 .getSuperclass()) {
106             try {
107                 return superClass.getDeclaredField(filedName);
108             } catch (NoSuchFieldException e) {
109                 // Field 不在当前类定义, 继续向上转型
110             }
111         }
112         return null;
113     }
114 
115     /**
116      * 直接调用对象方法, 而忽略修饰符(private, protected)
117      * 
118      * @param object
119      * @param methodName
120      * @param parameterTypes
121      * @param parameters
122      * @return
123      * @throws InvocationTargetException
124      * @throws IllegalArgumentException
125      */
126     public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes, Object[] parameters)
127             throws InvocationTargetException {
128 
129         Method method = getDeclaredMethod(object, methodName, parameterTypes);
130 
131         if (method == null) {
132             throw new IllegalArgumentException("Could not find method ["   methodName   "] on target ["   object   "]");
133         }
134 
135         method.setAccessible(true);
136 
137         try {
138             return method.invoke(object, parameters);
139         } catch (IllegalAccessException e) {
140             System.out.println("不可能抛出的异常");
141         }
142 
143         return null;
144     }
145 
146     /**
147      * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
148      * 
149      * @param object
150      * @param fieldName
151      * @param value
152      */
153     public static void setFieldValue(Object object, String fieldName, Object value) {
154         Field field = getDeclaredField(object, fieldName);
155 
156         if (field == null)
157             throw new IllegalArgumentException("Could not find field ["   fieldName   "] on target ["   object   "]");
158 
159         makeAccessible(field);
160 
161         try {
162             field.set(object, value);
163         } catch (IllegalAccessException e) {
164             System.out.println("不可能抛出的异常");
165         }
166     }
167 
168     /**
169      * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
170      * 
171      * @param object
172      * @param fieldName
173      * @return
174      */
175     public static Object getFieldValue(Object object, String fieldName) {
176         Field field = getDeclaredField(object, fieldName);
177 
178         if (field == null)
179             throw new IllegalArgumentException("Could not find field ["   fieldName   "] on target ["   object   "]");
180 
181         makeAccessible(field);
182 
183         Object result = null;
184 
185         try {
186             result = field.get(object);
187         } catch (IllegalAccessException e) {
188             System.out.println("不可能抛出的异常");
189         }
190 
191         return result;
192     }
193 }

反射工具类

7.JDBC的批管理操作

如何技巧获得那些一而再呢?--想要营造这一个延续,你必要登记叁个使得---嗯~正是那一个代码   Class.forName("com.mysql.jdbc.Driver");  

比释迦牟尼佛说:修改复制行内容快速键。

3.....

2:编写通用查询:

 1 package com.yinfu.test;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.sql.Connection;
 6 import java.sql.DriverManager;
 7 import java.sql.PreparedStatement;
 8 import java.sql.ResultSet;
 9 import java.sql.ResultSetMetaData;
10 import java.sql.SQLException;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Properties;
16 
17 import org.junit.Test;
18 
19 import com.yinfu.dao.Employee;
20 import com.yinfu.utils.JDBCUtils;
21 import com.yinfu.utils.ReflectionUtils;
22 
23 public class JDBCTest {
24 
25     @Test
26     public void testUpdate(){
27         //查
28         String sqlQuery = "select id, name, password from employee where name = ?";
29         Object employee = testQueryObject(Employee.class,sqlQuery,"zhangsan");
30         System.out.println("利用反射=" employee);
31     }
32     
33     public <T> T testQueryObject(Class<T> clazz, String sql, Object ... args){
34         T object = null;
35         Map<String, Object> map = new HashMap<String, Object>();
36         Connection conn = null;
37         PreparedStatement ps = null;
38         ResultSet resultSet = null;
39         try {
40             //创建连接
41             conn = JDBCUtils.getConnetions();
42             //创建prepareStatement对象,用于执行SQL
43             ps = conn.prepareStatement(sql);
44             //将参数赋值到sql的所需参数中
45             for(int i = 0 ; i < args.length ; i  ){
46                 ps.setObject(i 1, args[i]);
47             }
48             //一:根据SQL语句和传入的参数得到结果集,此结果集中全部是纯数据值,不带列名;
49             resultSet = ps.executeQuery();
50             //二:利用ResultSet对象得到ResultSetMetaData对象jdbc的元数据,根据此对象可以知道SQL语句查询了哪些列,以及列的别名是什么(具体参考JDBC的API进行学习)
51             ResultSetMetaData rsmd = resultSet.getMetaData();
52             while(resultSet.next()){
53                 //把列名的别名和列值分别取出来放到map中作为键值出现(resultSet和rsmd结合得到的就是一个表,和数据库表一样),由ResultSetMetaData得到每一列的别名,                   //由ResultSet 得到对应的值
54                 for(int i=0;i<rsmd.getColumnCount();i  ){
55                     String columnLabel = rsmd.getColumnLabel(i 1);
56                     Object columnValue = resultSet.getObject(columnLabel);
57                     map.put(columnLabel, columnValue);
58                 }
59             }
60             //利用反射创建class对应的对象
61             object = (T) clazz.newInstance();
62             //遍历map对象,用反射填充对象属性值
63             for(Map.Entry<String, Object> entry : map.entrySet()){
64                 String fieldName = entry.getKey();
65                 Object fieldValue = entry.getValue();
66                 //利用反射工具類(属性名对应map的key值,属性名对应map的value值)
67                 ReflectionUtils.setFieldValue(object, fieldName, fieldValue);
68             }
69         } catch (Exception e) {
70             e.printStackTrace();
71         }finally{
72             JDBCUtils.release(resultSet, ps, conn);
73         }
74         return object;
75     }
76 }

选择JDBC的预编写翻译对象开始展览CRUD操作(器重)

它是通过反射的建制来获得的,不打听反射?嗯~那你难以忘怀就完了 哈哈哈

1.点击window菜单->preferences子菜单->general->keys,进入火速键管理分界面

|-Statement接口:用于施行静态SQL语句

 3:利用BeanUtils工具类落成查询多条记下(增多commons-beanutils.jar和commons-logging.jar):

图片 8图片 9

  1 package com.yinfu.test;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.sql.Connection;
  6 import java.sql.DriverManager;
  7 import java.sql.PreparedStatement;
  8 import java.sql.ResultSet;
  9 import java.sql.ResultSetMetaData;
 10 import java.sql.SQLException;
 11 import java.util.ArrayList;
 12 import java.util.HashMap;
 13 import java.util.List;
 14 import java.util.Map;
 15 import java.util.Properties;
 16 
 17 import org.apache.commons.beanutils.BeanUtils;
 18 import org.junit.Test;
 19 
 20 import com.yinfu.dao.Employee;
 21 import com.yinfu.utils.JDBCUtils;
 22 import com.yinfu.utils.ReflectionUtils;
 23 
 24 public class JDBCTest {
 25 
 26     @Test
 27     public void testUpdate(){
 28         //查多条
 29         String sqlQueryList = "select id, name, password from employee";
 30         List<Employee> testQueryList = testQueryList(Employee.class,sqlQueryList);
 31         System.out.println("查询多条:" testQueryList);
 32         
 33     }
 34     
 35      //查询多条记录
 36     public <T> List<T> testQueryList(Class<T> clazz, String sql, Object ...args ){
 37         //用于接收返回值
 38         T object = null;
 39         List<T> list = new ArrayList<>();
 40         Connection conn = null;
 41         PreparedStatement rs = null;
 42         ResultSet resultSet = null;
 43         try {
 44             //获取数据库连接
 45             conn = JDBCUtils.getConnetions();
 46             rs = conn.prepareStatement(sql);
 47             //填充占位符
 48             for(int i = 0; i < args.length; i  ){
 49                 rs.setObject(i 1, args[i]);
 50             }
 51             //获取结果集
 52             resultSet = rs.executeQuery();
 53             //1:准备一个List<Map<String, Object>>集合,其中key为列名,value为列值,每一个map对应一条记录
 54             List<Map<String, Object>> listMap = new ArrayList<>();
 55             //2:得到jdbc的元数据
 56             ResultSetMetaData rsmd = rs.getMetaData();
 57             while(resultSet.next()){
 58                 Map<String, Object> map = new HashMap<>();
 59                 for(int i = 0; i < rsmd.getColumnCount(); i  ){
 60                     //游标是从1开始的
 61                     String columnLabel = rsmd.getColumnLabel(i 1);
 62                     Object columnValue = resultSet.getObject(columnLabel);
 63                     map.put(columnLabel, columnValue);
 64                 }
 65                 //3:把一条记录map放入到listMap中
 66                 listMap.add(map);
 67             }
 68             
 69             /*//上面一段代码可以这样写
 70             List<String> labelList = getColumnLabels(resultSet);
 71             while(resultSet.next()){
 72                 Map<String, Object> map = new HashMap<>();
 73                 for(String columnLabel : labelList){
 74                     Object columnValue = resultSet.getObject(columnLabel);
 75                     map.put(columnLabel, columnValue);
 76                 }
 77                 //3:把一条记录map放入到listMap中
 78                 listMap.add(map);
 79             }*/
 80             
 81             //4:遍历listMap集合,把其中的每一个map都转换成对应的Class对象,并放到list中进行返回
 82             if(listMap.size()>0){
 83                 for(Map<String, Object> mapObj : listMap){
 84                     //有记录就通过反射得到对应的类对象
 85                     object = clazz.newInstance();
 86                     for(Map.Entry<String, Object> entry : mapObj.entrySet()){
 87                         String propertyName = entry.getKey();
 88                         Object propertyValue = entry.getValue();
 89                         //利用工具类beanutils进行实体类转换
 90                         BeanUtils.setProperty(object, propertyName, propertyValue);
 91                     }
 92                     list.add(object);
 93                 }
 94             }
 95             
 96         } catch (Exception e) {
 97             e.printStackTrace();
 98         }
 99         
100         return list;
101     }
102     
103     private List<String> getColumnLabels(ResultSet resultSet) throws SQLException{
104         ResultSetMetaData rsmd = resultSet.getMetaData();
105         List<String> list = new ArrayList<>();
106         for(int i = 0; i<rsmd.getColumnCount(); i  ){
107             list.add(rsmd.getColumnLabel(i 1));
108         }
109         return list;
110     }
111 }

询问多条记下

[if !supportLists]1.1 [endif]1.JDBC的概述

connection = DriverManager.getConnection(url, user, password);这一句话的是用来获得连接的 ,那三个参数分别是   数据的地方,jdbc:mysql://IP地址:端口号/数据库的名目

图片 10

int        executeUpdate(String sql)推行更新操作的sql语句(create/alter/drop/insert/update/delete)

 4:可以用收获PrepareStatement的另二个重载方法得到,然后再用此目的的getGeneratedKeys()方法取得插入的多寡时自动生成的ID的结果集,此结果集就一列,列名叫:GENERATED_K。

JDBC:(Java DataBase Connectivity Java数据库总是).

嗯~然年再将弹指间什么通过jdbc向数据库写入数据

 

ResultSet      executeQuery(String sql)实践查询操作的sql语句

*是一种用于实施SQL语句的Java 的API.可以为两种关系型数据库提供联合的访问.它是由一组采纳Java语言编写的类或接口组成.

public int insertStuByStatement() {
        String sql1 = "insert into stu(sname,sage) values('aaa',1)";
        String sql2 = "insert into stu(sname,sage) values('bbb',1)";
        String sql3 = "insert into stu(sname,sage) values('ccc',1)";
        Connection connection = getConnection();// 获得数据库的连接
        Statement stmt = null;
        try {
            stmt = (Statement) connection.createStatement();
            connection.setAutoCommit(false);
            stmt.addBatch(sql1);//批量添加sql语句
            stmt.addBatch(sql2);//批量添加sql语句
            stmt.addBatch(sql3);//批量添加sql语句
            //一次性执行
            stmt.executeBatch();
            connection.commit();
            System.out.println("批处理成功");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }

 

(select)

简说:用java语言编写的一组用于访问关系型数据库的接口和类.

那边运用的statement 来贯彻的,写出您要操作的 sql语句。(提一下,一般那几个操作都以位于DBUtil类中的额 ,那几个办法本人也是献身DBUtil的)。

2.在此间能够查找全数作用的神速键,须要修改或新扩充时,点击须求修改或新扩展的吩咐,在binding里安装快速键

(能够幸免流入漏洞,对sql语句进行预编写翻译)

作用:使用Java语言总是到数据库

第二步:依据上面的概念的点子获得数据库。

图片 11

|-PreparedStatement接口:用于奉行预编写翻译的SQL语句(是Statement的子接口)

使得:三个设备之间的通讯桥梁.

下边就是获得二个Statement 对象,然后经过那么些指标的stmt.executeBatch();就能够在数据库中实施方才就的语句了,那样就完事了静态插入数据。

 

int      executeUpdate()实施更新操作的sql语句

Java语言要一而再数据库必须选用数据库的驱动

那动态插入数据是哪些的呢 ?-----那正是用到了另贰个能够落到实处语句的目的PreparedStatement

3.安装完飞快键后,还索要设置在曾几何时能够动用该快捷键,eclipse提供种种场所供选取,一般选拔In Windows(即在eclipse窗口激活状态)就可以

ResultSet     executeQuery()实行查询操作的sql语句

本质:

平素上代码吧 

图片 12

4......

SUN公司提供了一组接口,各类数据库生产商提供了那套接口的完成.(那组正式正是JDBC规范.)

public int insertStu(String sname,int sage){
        String sql = "insert into stu(sname,sage) values(?,?)";
        Connection connection = getConnection();//获得数据库的连接
        PreparedStatement ps = null;
        int i = 0;
        try {
            ps  = (PreparedStatement) connection.prepareStatement(sql);
            ps.setString(1, sname);
            ps.setInt(2, sage);

            i=ps.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if (ps!=null) {
                ps.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }

 

|-ResultSet接口:结果集对象。存款和储蓄全部数据库查询的结果,用该目标开始展览数量遍历。

[if !supportLists]1.2 [endif]02_JDBC的入门(写)

概念的插入方法有了七个参数的数值

完结以上操作,点击OK即成功安装

booleannext():把光标移动到下一行。借使下一行有数据,再次回到true,假若未有下一行数据,重返false。

先表明下,再写

与statement的差异在哪吧?--三个是sql字符串语句的分别,多了“?”,成效是---看上面这两行代码

图片 13

getXXX(列索引|列字段名称):获取字段的数目

安装专门的工作空间的编码为utf-8

 ps.setString(1, sname);
 ps.setInt(2, sage);
 ps.set****(a,b)有两个参数,sql语句中也有两个?,所以参数a,代表的是sql语句的第几个“?”,如果参数是1,则说明sql语句中第一个“?”的位置替换为参数b,
 如果 同理如果参数是2,则说明sql语句中第一个“?”的位置替换为参数b.这样就做到了动态的插入数据,我们只要在调用插入方法的时候传入想要插入的数据就好了,不用每次都写新的sql语句。
 对于 i=ps.executeUpdate();语句,它返回的这次你的数据库操作后有有几条数据有影响.这种方法对于插入,当然是i=1了

但是对于产出和修改的就不是一定了,删除修改我直接贴代码了就不再做讲解

//修改
public int updateStu(int sage,String sname){
        String sql = "updae stu set sage = ? where sname = ?";
        Connection connection = getConnection();
        PreparedStatement ps =null;
        int i  = 0;
        try {
            ps = (PreparedStatement) connection.prepareStatement(sql);
            ps.setInt(1, sage);
            ps.setString(2, sname);

            i  = ps.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if (ps!=null) {
                ps.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }
    //删除
        public int deleteStu(String sname,int sage) {
            String sql = "delete from stu where sname=? and sage = ?";
            Connection conn = getConnection();//获得数据库连接
            PreparedStatement ps = null;
            int i = 0;
            try {
                ps = (PreparedStatement) conn.prepareStatement(sql);
                ps.setString(1, sname);
                ps.setInt(2,sage );

                i = ps.executeUpdate();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                try {
                    if(ps != null)
                        ps.close();
                }catch (Exception e) {
                    // TODO: handle exception
                }
            }
            return i;

        }

3、设置专门的工作空间的编码

i"=��)

SQL脚本:

 

 图片 14

先是种连接操作数据库的点子       存在sql注入的高危害

create database web_test3;

数据库最重要的是什么---查询数据,相对于增删改--查可能稍微繁琐一点
代码如下:

/**
     * 查询所有学生
     * @return
     */
    public ArrayList<Stu> queryStu(){
        String sql = "select * from stu ";// select *  或的字段的顺序和数据库中的是一致
        Connection conn = getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        ArrayList<Stu> stus = new ArrayList<Stu>();//此集合用于存储每一个学生对象
        try {
            ps = (PreparedStatement) conn.prepareStatement(sql);
            rs = ps.executeQuery();
            //遍历rs
            while(rs.next()) {//true表示有下一条数据
                int id = rs.getInt("id");
                String sname = rs.getString("sname");
                int sage = rs.getInt("sage");
                //创建stu对象
                Stu stu = new Stu(id, sname, sage);
                //收集对象
                stus.add(stu);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if(rs != null)
                    rs.close();
                if(ps != null)
                    ps.close();
            }catch (Exception e) {
                // TODO: handle exception
            }
        }

        return stus;
    }

 

首先步: 加载驱动

Class.forName("com.mysql.jdbc.Driver");

use web_test3;

讲一下关键的地点     ResultSet rs

null;  那么些目的存款和储蓄的一个查询的结果集合。select * from stu那个再次回到的 应该是查询的学生表中每一种学员的具有数据,

为此rs就可以积累那样的二个会晤,然后通过遍历获得在这之中的数额,将数据赋值给多个学员对目的,将目的插手到聚集中,就拿走可表中持有的数量~

 

此次讲的严重性是基础部分,等后一次持续深究JDBC联合别的的一些操作~

Class.forName("com.mysql.jdbc.Driver");

二、JUnit单元测试

第二部:创造链接数据库

Connection conn=driverManger.getConnection(url,user,password);

create table user(

1、介绍:JUnit是贰个java语言的单元测试框架。属于第三方工具,一般景况下要求导入jar包,但是多数java开采意况已经济同盟龙了JUnit作为单元测试工具。

第三部:创建Statement对象

Statement statement=conn.createStatement();

id int primary key auto_increment,

创建“day07”java项目,并创建“cn.itcast.a_junit”包 

第四步:创建Sql语句

String sql="sql语句";

username varchar(20),

 图片 15

第五步:执行sql语句

借使地点的sql语句是DDL. DML语句   就动用如下代码:

statement.executeUpdate(sql);   能够用int类型去领受

只要地方的sql语句是DQL语句,,就是用如下代码:

statement.executeQuery(sql);   能够用int类型区接受

password varchar(20),

2、编写测试类,轻巧掌握能够用来代替java的main方法

第六步:  关闭  

调用close方法        conn         statement

if(conn!=null){conn.close()}    statement和conn 一样

nickname varchar(20),

3、在测试类方法上增加阐明@Test

第三种艺术   是用Statement的子接口   PreparedStatement   不会存在sql注入风险

age int

4、评释修饰方法需求:public void 方法名(){...},方法名自定义提议test初阶

率先步: 加载驱动

Class.forName("com.mysql.jdbc.Driver");

);

图片 16

第二步:成立链接数据库

Connection conn=driverManger.getConnection(url,user,password);

insert into user values (null,'aaa','123','小丽',34);

5、增添STS中合拢的Junit库,鼠标点击“@Test”,使用火速键“ctrl 1”,点击“Add Junit...”

第三步:创建sql语句

insert into user values (null,'bbb','123','大王',32);

图片 17

第四步:创建Preparedstatement对象

Preparedstatement pstat=conn.preparedstatement(sql);

实施DDL,DML语句代码如下

ResultSet rs=pstat.executeupdate();     Result是个集聚    

推行DQL语句代码如下

ResultSet rs=pstat.executeQuery();

第五步:关闭

ResultSet也急需关闭

conn    pstat      rs  四个都要关门

insert into user values (null,'ccc','123','小明',28);

结果

statement 和 Preparedstatement的区别:

insert into user values (null,'ddd','123','大黄',21);

图片 18

1...语法不一样   

  statement:实施的事静态sql语句

Preparedstatement:先实行预编写翻译SQL语句: 能够用 ? 进行参数占位  后边给参数赋值

    比如1:      String sql="select * from user where uid=?;";

                     pstat.setInt(1,值);

                    int是基于sql语句 列字段(Uid)的类型,   1是第多少个?    值是填?的  

    比如2:         String sql ="INSERT INTO student(NAME,gender)

VALUES(?,?)";//预编译sql:使用?号代替参数值。八个?号表示八个参数值

引入数据库的驱动.

6、使用:选中方法右键,施行当前格局;选中类名右键,推行类中保有办法(方法必须表明@Test)

2...规律分裂

statement:无法张开缓存

Preparedstatement:能够张开缓存,实施功效比statement快

只顾:复制驱动包过来后,一定要选中, add to Build Path

图片 19

3...白山难点

statement:无法防守sql注入

Preparedstatement:可避防备sql注入

1.加载驱动.

7、常用表明

JDBC的批管理:

Statement批处理:

                     void      addBatch(String sql)增加sql到缓存区(一时半刻不发送)

                     int[]      executeBatch()实施批处理命令。发送全部缓存区的sql

                      void       clearBatch()清空sql缓存区

PreparedStatement批处理:

                  void     addBatch()增加参数到缓存区

                 int[]      executeBatch()推行批处理命令。发送全体缓存区的sql

                void      clearBatch()清空sql缓存区

2.得到连接.

    @Test,用于修饰必要试行的章程

Mysql不补助批管理优化,也不支持PreparedStatement对象优化

赢得说话(Statement )对象

    @Before,测试方法前实施的艺术

Oracle扶助批管理优化,帮忙PreparedStatement对象优化。

3.执行SQL

    @After,测试方法后举办的章程

4.保释财富.

图片 20

public class JDBCDemo1 {

8、常见使用不当,假使未有增加“@Test”,使用“Junit Test”实行运作,将抛极度

@Test

图片 21

/**

三、JDBC

* JDBC的入门

1、什么是JDBC

 */

JDBC(Java DataBase Connectivity)便是java数据库连接,轻松地说就是用java语言来操作数据库。原本笔者们操作数据库是在调整台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句

public void demo1() throws Exception{

<1>JDBC是一种用于奉行SQL语句的java API

// 1.加载驱动

<2>JDBC可以为二种关周全据库提供统一访问入口

Class.forName("com.mysql.jdbc.Driver");

<3>JDBC由一组java工具类和接口组成

// 2.拿走三番五次

2、JDBC原理

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "abc"); //注意:密码改成你的密码

开始时代SUN集团的禀赋们想编写一套能够连接天下全数数据库的API,可是当她们刚刚开首时就意识那是不足达成的职责,因为种种厂家的数据库服务器差距太大了。后来SUN始发与数据库厂商们批评,最后得出的定论是,由SUN提供一套访问数据库的标准(便是一组接口),并提供连接数据库的磋商正式,然后所有人家数据库厂商会遵循SUN的科班提供一套访问自身公司的数据库服务器的API出现。SUN提供的业内命名称为JDBC。而相继商家提供的,服从了JDBC标准的,能够访问自数据库的API被叫做驱动。

// 3.基本操作:实行SQL

图片 22

// 3.1获得实行SQL语句的对象

JDBC是接口,而JDBC驱动才是接口的实现,未有驱动不或许成功数据库连接!每一个数据库商家都有温馨的驱动,用来三番五次本人集团的数据库。

Statement statement = conn.createStatement();

本来还恐怕有第三方企业特地为某一数据库提供驱动,那样的驱动往往不是开源免费的!

// 3.2编写SQL语句:

3、JDBC核心类(接口)介绍

String sql = "select * from user";

JDBC中的大旨类有:DriverManager、Connection、Statement和ResultSet

// 3.3执行SQL:

DriverManager(驱动管理器)的遵从有七个

ResultSet rs = statement.executeQuery(sql);

<1>注册驱动:那能够让JDBC知道要利用的是哪位驱动;

// 3.4遍历结果集:

<2>获取Connection:如果能够获得到Connection,那么注明已经与数据库连接上了。

while(rs.next()){

    Connection对象表示连接,与数据库的报道都是由此这些指标实行的;

System.out.print(rs.getInt("id") " ");

<3>Connection最为根本的二个艺术便是用来收获Statement对象;

System.out.print(rs.getString("username") " ");

<4>Statement是用来向数据库发送SQL语句的,那样数据库会推行发送过来的的SQL语句

System.out.print(rs.getString("password") " ");

<5>void executeUpdate(String sql):实行更新操作(insert、update、delete等);

System.out.print(rs.getString("nickname") " ");

<6>ResultSet executeQuery(String sql):实行查询操作,数据库在奉行查询后会重回查询结果,查询    结果正是ResultSer;

System.out.print(rs.getInt("age"));

    ResultSet对象表示查询结果集,只有在实施查询操作后才会有结果集的产生。结果集是一个人二维     的表格,有行有列。操作结果集要学习活动ResultSet内部的“行光标”,以及获得当前行上的数目

System.out.println();

<7>boolean next():使“行光标”移动到下一行,并回到移动后的行是否存在;

}

<8>xxx getxxx(int col):获取当前行内定列上的值,参数正是列数,列数从1上马,而不是0

// 4.保释财富

4、JDBC开垦步骤

rs.close();

4.1 导入mysql数据库的驱动jar包:

statement.close();

<1>创设lib目录,用于存放当前项目须求的具备jar包

conn.close();

<2>选拔jar包,右键实行build path/Add to Build 帕特h

}

图片 23

}

[if !supportLists]1.3 [endif]03_DriverManager的介绍

4.2 注册驱动

问题:

挂号驱动就唯有一句话:Class.forName("com.mysql.jdbc.Driver"),

DriverManager对象有哪些功用?

上边包车型地铁内容都以对那句代码的分解。以后我们的代码中,与登记驱动相关的代码只有这一句。

Ø为啥未有行使registerDriver()注册驱动?

<1>剖析步骤1:JDBC规范定义驱动接口:java.sql.Driver,

Ø获取连接的url路线的意思?

               MySql驱动包提供了达成类:com.mysql.jdbc.Driver 
<2>剖析步骤2:DriverManager工具类,提供注册驱动的措施registerDriver(),

1.DriverManager对象四个效益:①、注册驱动和②、获取连接;

               方法的参数是java.sql.Driver,所以大家能够通过如下语句进行挂号

2.怎么选取未有动用registerDriver注册驱动?

               DriverManager.registerDriver(new com.mysql.jdbc.Driver());

DriverManager类:

               以上代码不推荐使用,存在两下边相差:

原先这么写:

               1.硬编码,早先时期不易于程序扩大和掩护

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

               2.驱动被登记五回

com.mysql.jdbc.Driver源码:

<3>分析步骤3:一般来说开采大家运用Class.forName()加载一个运用字符串描述的驱动类。

未来那般写:

               即便利用Class.forName()将加载到内存,该类的静态代码将自动推行

Class.forName(“com.mysql.jdbc.Driver”);//强制加载class到内部存款和储蓄器

               通过询问com.mysql.jdbc.Driver源码,大家开掘Driver类“主动”将和谐开始展览注册 

结论:直接调用registerDriver方法会变成驱动加载2次.

DriverManager类的registerDriver()方法的参数是java.sql.Driver,但java.sql.Driver是一个接口,实现类由mysql驱动来提供,mysql驱动中的java.sql.Driver接口的完毕类为com.mysql.Driver那么注册驱动的代码如下:

[if !supportLists]3.[endif]获得连接的url路线的意思?

    DriverManager.registerDriver(new com.mysql.jdbc.Driver());

[if !supportLists]1.4 [endif]04_Connection的介绍

    上边的代码即便可以登记驱动,可是出现硬编码(代码信赖mysql驱动jar包),如果今后想连接Oracle数据库,那么必供给修改代码。并且实际这种注册驱动的方法是登记了四次驱动!

[if !supportLists]Ø [endif]Connection对象有哪些效能?

    JDBC中规定,驱动类在被加载时,需求协和“主动”把自身注册到DriverManager中,上面来探视com.mysql.jdbc.Driver类的源代码:

有多个成效:①、创立实施SQL的Statement(语句)对象;②、处监护人务

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch(SQLException E) {
            throw newRuntimeException("Can't register driver!");
        }
    }
……
}

功能一、创制实施sql语句的指标:

com.mysql.jdbc.Driver类中的static块会创立本类对象,并注册到DriverManager中,那注脚只要去加载com.mysql.jdbc.Driver类,那么就能够推行那几个static块,从而也就能够把com.mysql.jdbc.Driver注册到DriverManager中,所以能够把挂号驱动类的代码修改为加载驱动类。

效益二:管理作业

Class.forName("com.mysql.jdbc.Driver");    

总结:

[if !supportLists]1.[endif]Connection对象的效果?

4.3 获取连接

赢得语句对象

代码:Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydbl","root","root")

Statement

获得连接须求两步,一是应用DriverManager来注册驱动,二是利用DriverManager来获取Connection对象。

 CallableStatement(后面Oracle说)

    获取连接的也只有一句话代码:

 PreparedStatement

    DriverManager.getConnection(url,username,password);

治本事务

    其中username和password是登陆数据库的用户名和密码

setAutoCommit(false);//手动开启事务

    url相对复杂一点,它是用来找到要连接数据库的“网站”,就好比你要在浏览器中搜索百度时,也亟需提供二个url。上边是mysql的url:

...

    jdbc:mysql://localhost:3306/mydbl

...

    JDBC规定url的格式由三有个别组成,每一种部分中档使用冒号分割。

commit()

    <1>第一局地是jdbc,那是原则性的;

rollback();

    <2>第二片段是数据库名称,那么连接mysql数据库,第二有些当然是mysql了;

[if !supportLists]1.5 [endif]05_Statement的介绍

    <3>第三有的是由数据库商家规定的,我们须要领悟各种数据库厂家的渴求,mysql的第三有些各自      由数据库服务器的IP地址(localhost)、端口号(3306),以及database名称(mybdl)组成

[if !supportLists]Ø [endif]Statement对象有何功能?

    下边是得到连接的讲话: 

有五个职能:①、实施sql语句;②、进行批管理

    Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/web08","root","root");

作用一:执行sql语句

     还足以在url中提供参数:

功能二:实行批管理:正是把几条sql语句增添到Statement对象命令列表中,贰次性奉行多条sql语句。

    jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=UTF8

[if !supportLists]1.6 [endif]06_ResultSet的介绍

    useUnicode参数钦命那些一连数据库的进程中,使用的字节集是Unicode字节集;

ResultSet代表select查询后的结果集

    characterEncoding参数钦命java程序连接数据库的经过中,使用的字符集编码为UTF-8编码。注意,mysql中钦点UTF-8编码给出的是UTF8,而不是UTF-8

方法:

*向下移动光标.

4.4 获得说话执行

*得到结果聚集整形数据.

String sql="insert into category(cid,cname) values('c007','分类')";

*获得结果聚焦字符串类型的多少:

Statement stmt=con.createStatement();

...

在获取Connection之后,表明已经与数据库连接上了,上边是通过Connection获取Statement对象的代码:

遍历结果集:

    Statement stmt=con.createStatement();

* while(rs.next()){

    Statement是用来向数据库发送要推行的SQL语句的

int id = rs.getInt("id");

常用方法:

String username = rs.getString("username");

执行SQL语句:

String password = rs.getString("password");

    <1>int executeUpdate(String sql);---执行insert update delete语句.(DML语句)

System.out.println(id "    " username "    " password);

    <2>ResultSet executeQuery(String sql);---执行select语句(DQL语句)

}

    <3>boolean execute(String sql);---试行select重回true,推行此外的话语重返false 

获得结果集中的数据:

        假设回去true,需求使用getResultSet()获得查询结果

* int id = rs.getInt("id");

        假诺回去false,须求运用getUpdateCount()获得影响行数

String username = rs.getString("username");

试行批管理:(可选)

String password = rs.getString("password");

    addBatch(String sql);

假诺结果聚焦唯有一条记下:

    clearBatch();

* if(rs.next()){

    executeBatch();

...

}

4.5 预管理对象

原理:

使用管理目的时,指出每条sql语句全部的其实参数,都应用逗号分隔

总结:

String sql="insert into category(cid,cname) values(?,?)";

   1. Result rs = statement.executeQuery(“select * from user”);

PreparedStatement psmt=con.prepareStatement(sql);

   2.while(rs.next()) {

常用方法:

       rs.getInt(“id”);

执行SQL语句:

rs.getString(“username”);

    <1>int executeUpdate(String sql);---执行insert update delete语句.(DML语句)

rs.getObject(“password”);

    <2>ResultSet executeQuery(String sql);---执行select语句(DQL语句)

rs.getInt(4);

    <3>boolean execute(String sql);---施行select再次来到true,实践其它的语句重返false 

}

设置实际参数:

[if !supportLists]1.7 [endif]07_JDBC的财富的自由

    setxxx(int,T)通过setter方法将?占位符替换来实际上参数

Connection的施用标准:全心全意要晚创造,尽量早释放!!!

    举例:setString()实际参数类型为hi字符串

try{

施行批管理:(可选)

..

    addBatch; 增多批处理的其实参数,需求调方法前施行对应setter方法

...

    clearBatch();

}catch(){...}

    executeBatch();

finally {....}

要明白,看看代码,早上写

4.6 处理结果集

[if !supportLists]Ø [endif]控释能源的标准代码:一般把自由能源的代码放到finally里面去试行

ResultSet便是一张二维的表格,它当中有多个“行光标”,光标暗中认可地方在“第一行上方”,大家得以调用rs对象的next()方法把“行光标”向下活动一行,当第贰回调用next()方法时,“行光标”就到了第一行记录的地点,那时就足以利用ResultSet提供的getxxx(int col)方法来收获钦命列的数量了:

finally {

    rs.next();//光标移动到第一行

//5、方法能源

    rs.getInt(1);//光标移动到第一列的数目

if (resultSet!=null) {

图片 24

try {

    当你使用rs.getInt(1)方法时,你必须能够毫无疑问第1列的数据类型就是int类型,要是你无法自然,那么最佳应用rs.getObject(1)。在ResultSet类中提供了一雨后鞭笋的getxxx()方法,比较常用的章程有:

resultSet.close();

    Object getObject(int col)

} catch (SQLException e) {

    String getString(int col)

e.printStackTrace();

    int getInt(int col)

}

    double getDouble(int col)

resultSet=null;

}

4.7 释放能源

if (statement!=null) {

与IO流同样,使用后的东西都亟需关闭,关闭的各类是先获得的后关门,后拿走的先关闭

try {

    rs.close();

statement.close();

    stmt.close();

} catch (SQLException e) {

    con.close;

e.printStackTrace();

}

4.8 完成查询操作代码

statement=null;

    public static Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url ="jdbc:mysql://localhost:3306/web08";
        return DriverManager.getConnection(url, "root", "root");
    }

    @Test
    public void query() throws Exception{
        Connectioncon = getConnection();
        Statementstmt = con.createStatement();
        String sql ="select * from user";
        ResultSet rs= stmt.executeQuery(sql);
        while(rs.next()){
            String username = rs.getString(1);
            String password = rs.getString(2);
            System.out.println(username  ", "   password);
        }
    }

}

if (conn!=null) {

4.9 规范化代码

try {

所谓标准化代码就是随意是或不是出现非常,都要关闭ResultSet、Statement,以及Connection

conn.close();

    @Test
    public void query() {
        Connection con = null;
        Statement stmt = null;
        ResultSet rs= null;
        try {
            con = getConnection();
            stmt =con.createStatement();
            String sql = "select * from user";
            rs =stmt.executeQuery(sql);
            while(rs.next()){
                String username = rs.getString(1);
                String password = rs.getString(2);
                System.out.println(username  ", "   password);
            }
        } catch(Exceptione) {
            throw newRuntimeException(e);
        } finally {
            try {
                if(rs != null)rs.close();
                if(stmt != null) stmt.close();
                if(con != null)con.close();
            } catch(SQLExceptione) {}
        }
    }

} catch (SQLException e) {

4.10 案例:查询全数

e.printStackTrace();

}

图片 25

conn=null;

图片 26

}

5、JDBC对象介绍

}

5.1JDBC中的首要类(接口)

1、为啥对象调用了close()方法之后还要把对象手动赋值为null?

<1>DriverManager

能源自由的一段正式代码:

<2>Connection

// 4.刑释能源.

<3>Statement

if (rs != null) {

<4>ResultSet

try {

5.2 DriverManager

rs.close();

大家之后只供给会用DriverManager的getConnection()方法就能够:

} catch (SQLException e) {

<1>Class.forName("com.mysql.jdbc.Driver");

e.printStackTrace();

<2>String url="jdbc:mysql://localhost:3306/web08";

}

<3>String username="root"

rs = null; // 为了让JVM垃圾回收更早回收该对象.

<4>String password="root"

}

<5>Connection con=DriverManager.getConnection(url,username,password);

if (stmt != null) {

try {

留神:下面代码恐怕出现的三种相当:

stmt.close();

<1>ClassNotFoundException:这几个非常是在第1句上冒出的,出现这一个丰富有三个可能:

} catch (SQLException e) {

    (1)你未曾给出mysql的jar包;

e.printStackTrace();

    (2)你把类名打错了,查看类名是否com.mysql.jdbc.Driver。

}

<2>SQLException:那些特别出现在第5句,出现那些丰富正是多少个参数的标题,往往username和password一般不会出错,所以需求认真查阅url是不是打错

stmt = null;

    对于DriverManager.registerDriver()方法领会就能够,因为我们以后注册驱动只会用                 Class.forName(),而不会选取那些格局

}

5.3 Connection

if (conn != null) {

    Connection最为首要的秘诀正是赢得Statement:

try {

    (1)Statement stmt=con.createStatement();

conn.close();

    后边在就学ResultSet方法时,还要学习一下底下的方法

} catch (SQLException e) {

    (2)Statement stmt=con.createStatement(int,int);

e.printStackTrace();

5.4 Statement

}

    Statement最为关键的诀即使:

conn = null;

    <1>int executeUpdate(String sql):实行更新操作,即实行insert、update、delete语句,其实

}

    这几个办法也得以施行create table、alter table,以及drop table等语句,但我们相当少会使JDBC

总结:

    来实施这么些讲话;

try {

    <2>ResultSet executeQuery(String sql):实行查询语句,执行查询操作会再次来到ResultSet,即结果集;

//加载驱动

    <3>boolean execute():Statement还恐怕有四个boolean execute()方法,那些方法能够用来推行       增、删、改、查全体的SQL语句,该格局重回的是boolean类型,表示SQL语句是不是施行成功。

//获取连接

    假设使用execute()方法推行的是翻新语句,那么还要调用int getUpdateCount()来获得insert、       update、delete语句所影响的行数

//创建statement

    假使使用execute()方法实行的是查询语句,那么还要调用ResultSet、getResultSet()来赢得         select语句的查询结果

//执行SQL

5.5 ResultSet之滚动结果集(通晓)

//遍历结果集

    ResultSet代表结果集,它是二个二维的表格!ResultSet内部维护壹个行光标(游标),ResultSet提供了一密密麻麻的情势来运动游标:

}catch(Exception ex) {

    <1>void beforeFirst():把光标放到第一行的面前,这也是光标暗许的地方;

}finally {

    <2>void afterLast():把光标放到最后一行的后面;

//释放财富

    <3>boolean first():把光标放到第一行的岗位上,再次回到值表示调控光标是不是中标;

rs,stat,conn

    <4>boolean last():把光标放到末了一行的地方上;重返值表示调整光标是或不是中标

if (rs!=null) {

    <5>boolean isBeforeFirst():近来光标地点是或不是在率先行前边;

try {

    <6>boolean isAfterLast():脚下光标地方是或不是在最终一行的末尾;

rs.close();

    <7>boolean isFirst():眼下光标地点是否在第一行上;

}catch() {}

    <8>boolean isLast:时下光标地方是还是不是在终极一行上;

rs = null;

    <9>boolean next():把光标向下挪一行;

}

    <10>boolean relative(int row):周旋位移,当row为正数时,表示向下活动row行,为负数时     表示发展移动row行;

}

    <11>boolean absolute(int row):相对位移,把光标移动到内定行上;

[if !supportLists]1.8 [endif]08_JDBC的CRUD操作之保存(写)

    <12>int getRow():回去当前光标全体行

思路:

    下边方法分为两类,一类用来剖断游标地方的,另一类是用来移动游标的。要是结果集是不可滚动的,那么只可以选择next()方法来运动游标。而beforeFirst()、afterLast()、first()、last()、previous()、relative()方法都不能够使用!

加载驱动

    结果集是或不是支持滚动,要从Connection类的createStatement()方法谈到,约等于说创设的Statement决定了使用Statement创制的ResultSet是或不是补助滚动

获得一连

    Statement createStatement(int resultSetType,int resultSetConcurrency)

获得Statement对象,执行SQL

    resultSetType的可选值:

放飞能源

    (1)ResultSet.TYPE_FORWARD_ONLY:不滚动结果集

@Test

    (2)ResultSet.TYPE_SCROLL_INSENSITIVE:滚动结果集,但结果集数据不会再尾随数据库而变      化;

/**

    (3)ResultSet.TYPE_SCROLL_SENSITIVE:滚动结果集,但结果集数据不会在追随数据库而生成

*保留操作的代码达成

    能够看到,借使想使用滚动的结果集,大家应当采取TYPE_SCROLL_INSENSITIVE!其实非常的少有数据库驱动会支持TYPE_SCROLL_SENSITIVE的性状!经常我们也不要求查询到的结果集再遭逢数据库变化的熏陶

 */

    resultSetConcurrency的可选值:

public void demo1(){

    (1)CONCUR_READ_ONLY:结果集是只读的,不可能经过修改结果集而反向影响数据库;

Connection conn = null;

    (2)CONCUR_UPDATABLE:结果集是可更新的,对结果集的翻新能够反向影响数据库;

Statement stmt = null;

    平常可更新结果集这一“高档性子”大家也是不须要的!

try{

    获取滚动结果集的代码如下:

//注册驱动:

    Connection con=Statement stmt=con.createStatement(ResultSet.TYPE.SCROLL.INSENSITIVE,CONCUR_READ_ONLY);

Class.forName("com.mysql.jdbc.Driver");

    String sql=....//查询语句

//得到一连:

   ResultSet rs=stmt.executeQuery(sql);//那一个结果集是可滚动的

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

5.6 ResultSet之获取列数据

//试行操作:

    能够通过next()方法使ResultSet的游标向下活动,当游标移动到你要求的行时,就要求来取得该行的数量了,ResultSet提供了一多元的收获列数据的法子:

//制造实行SQL语句对象:

    (1)String getString(int columnIndex):得到钦点列的String类型数据;

stmt = conn.createStatement();

    (2)int getInt(int columnIndex):收获钦点列的int类型数据

//编写SQL语句:

    (3)double getDouble(int columnIndex):赢得内定列的double类型数据;

String sql = "insert into user values (null,'eee','123','阿黄',21)";

    (4)boolean getBoolean(int columnIndex):获得钦点列的boolean类型数据

//执行SQL语句:

    (5)Object getObject(int columnIndex):收获内定列的Object类型的数量

int num = stmt.executeUpdate(sql);

    上面包车型客车法子中,参数columnIndex表示列的目录,列索引从1开头,而不是0,这第一点与数组差别,借使你精通当前列的数据类型,那么能够动用getInt()之类的艺术来获得,假令你不知情列的品类,那么你应该运用getObject()方法类获取

if(num > 0){

    ResultSet还提供了一套通过列名称来收获列数据的情势:

System.out.println("保存用户成功!!!");

    (1)String getSting(String columnName):收获名叫columnName的列的String数据;

}

    (2)int getInt(String columnName):获取名称叫columnName的列的int数据

}catch(Exception e){

    (3)double getDouble(String columnName):获得名叫columnName的列的double数据;

e.printStackTrace();

    (4)boolean getBoolean(String columnName):获得名称叫columnName的列的boolean数据;

}finally{

    (5)Object getObject(String columnName):获得名字为columnName的列的Object数据

//资源自由:

6、SQL注入

if(stmt != null){

6.1 什么是SQL攻击

try {

    在急需用户输入的地方,用户输入的是SQL语句的片段,最后用户输入的SQL片段与我们dao中写的SQL语句合成叁个总体的SQL语句!比如用户在签到时输入的用户名和密码都以为SQL语句的局地

stmt.close();

6.2 演示SQL攻击 

} catch (SQLException e) {

    首先大家供给创建一张用户表,用来存款和储蓄用户的音信

e.printStackTrace();

    CREATE TABLE user(
    uid CHAR(32)PRIMARY KEY,
    username   VARCHAR(30)UNIQUE KEY NOT NULL,
    PASSWORD   VARCHAR(30)
    );
 
    INSERT INTO userVALUES('U_1001', 'zs', 'zs');
    SELECT * FROM user;

}

    将来用户表中只有一行记录,正是zs。

stmt = null;

    上面大家写贰个login()方法

}

    public void login(String username, String password) {
        Connectioncon = null;
        Statementstmt = null;
        ResultSet rs= null;
        try {
            con =JdbcUtils.getConnection();
            stmt =con.createStatement();
            String sql = "SELECT * FROM user WHERE "  
                    "username='"  username   
                    "'and password='"   password   "'";
            rs =stmt.executeQuery(sql);
            if(rs.next()){
                System.out.println("欢迎"  rs.getString("username"));
            } else {
                System.out.println("用户名或密码错误!");
            }
        } catch(Exception e) {
            throw newRuntimeException(e);
        } finally {
            JdbcUtils.close(con,stmt, rs);
        }       
    }

if(conn != null){

    上面是调用那些法子的代码:

try {

login("a' or 'a'='a", "a'or 'a'='a");

conn.close();

    那行当前会使大家登陆成功,因为输入的用户名和密码是SQL语句片段,最后与大家的login()方法中的SQL语句组合在一块,大家来探视组合在联合签字的SQL语句

} catch (SQLException e) {

SELECT * FROM tab_user WHERE username='a'or 'a'='a' and password='a' or 'a'='a'

e.printStackTrace();

6.3防止SQL攻击

}

    过滤用户输入的数额中是还是不是含有违规字符;

conn = null;

    分步兵高校验,先利用用户名来查询用户,假若查找到了,再比较密码;

}

    使用PreparedStatement

}

6.4 PreparedStatement是什么?

}

    PreparedStatement叫预编写翻译表明

[if !supportLists]1.9 [endif]09_JDBC的CRUD操作之修改操作(写)

    PreparedStatement是Statement的子接口,你能够应用PreparedStatement来替换Statement

    @Test

    PreparedStatement的好处:

/**

    (1)防止SQL攻击

*修改操作的代码达成

    (2)提升代码的可读性,以及可维护性

 */

    (3)升高功用

public void demo2(){

6.5 PreparedStatement的使用

Connection conn = null;

    使用Connection的prepareStatement(String sql):即创办它时就让它与一条SQL模板绑定;

Statement stmt  = null;

    调用PreparedStatement的setXXX()类别措施为问号设置值;

try{

    调用executeUpdate()或executeQuery()方法,但要注意,调用未有参数的秘技;

//注册驱动:

String sql = “select * from tab_studentwhere s_number=?”;
PreparedStatement pstmt =con.prepareStatement(sql);
pstmt.setString(1, “S_1001”);
ResultSet rs = pstmt.executeQuery();
rs.close();
pstmt.clearParameters();
pstmt.setString(1, “S_1002”);
rs= pstmt.executeQuery();

Class.forName("com.mysql.jdbc.Driver");

   在采纳Connection创制PreparedStatement对象时索要付出二个SQL模板,所谓SQL模板正是有“?”的SQL语句,个中“?”正是参数

//获得接二连三

    在赢得PreparedStatement对象后,调用它的setxxx()方法为“?”赋值,那样就可以赢得把模版产生一条完整的SQL语句,然后再调用PreparedStatement对象的executeQuery()方法赢得ResultSet对象

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

    注意:PreparedStatement对象独有的executeQuery()方法是从未参数的,而Statement的executeQuery()是急需参数(SQL语句)的。因为在开立PreparedStatement对象时早已让它与一条SQL模板绑定在一道了,所以在调用它的executeQuery()和executeUpdate()方法时就不再须要参数了。

//实行操作:

    PreparedStatement最大的裨益便是在乎重复使用同一模板,给予其分化的参数来重新的应用它。那才是的确升高作用的来头

//创立实践SQL语句的靶子:

    所依,在事后的付出中,无论什么状态,都去行使PreparedStatement,而不是使用Statement.

stmt = conn.createStatement();

7、使用JDBC完结分类表CRUD(增加和删除改查)的操作

//编写SQL语句:

7.1 案例剖析

String sql = "update user set password='abc',nickname='旺财' where id = 5";

运用JDBC对分类表category进行增加和删除改查操作

//执行SQL语句:

7.2 工具类

int num = stmt.executeUpdate(sql);

“获得再三再四”和“释放能源”五回代码就要后来的增加和删除改查全体机能中都存在,开辟中貌似境遇此种情状,将运用工具类的主意举办收取,从而完成代码的再一次使用

if(num > 0){

图片 27

System.out.println("修改用户成功!!!");

7.3 获得接二连三

}

图片 28

}catch(Exception e){

图片 29

e.printStackTrace();

7.4 释放能源

}finally{

纵然释放能源利用依次关闭多个对象,那么首先个指标关闭时抛出了特别,前面五个目的将不能够得逞释放能源,常常我们应用try-catch块举行管理

//能源自由:

措施1:多少个try-catch块,将财富自由,轻易驾驭

if(stmt != null){

图片 30

try {

图片 31

stmt.close();

措施2:try-catch-finally嵌套,能源自由时一旦出错,将通报调用者

} catch (SQLException e) {

图片 32

e.printStackTrace();

7.5 使用properties配置文件

}

开采中猎取一而再的4个参数(驱动、UMuranoL、用户名、密码)常常都设有配置文件中,方便中期维护,程序一旦供给转移数据库,只需求修改配置文件就能够

stmt = null;

平常情况下,大家习于旧贯使用properties文件,此文件大家将做如下须求:

}

<1>文件地点:任性,提出src下

if(conn != null){

<2>文件名称:大肆,扩充名叫properties

try {

<3>文件内容:一行一组数据,格式是“key=value”

conn.close();

    (1)key命名自定义,假若是多少个单词,习贯使用点分割。举个例子:jdbc.driver

} catch (SQLException e) {

    (2)value值不扶助普通话,借使急需利用非英文字符,将张开unicode调换

e.printStackTrace();

7.5.1 创制布局文件

}

右键/New/File,输入“db.properties”文件名

conn = null;

图片 33

}

图片 34

}

7.5.2 加载配置文件:ResourceBundle对象

}

ResourceBundle提供getBundle()方法用于只提供properties文件就能够,之后选取getString(key)通过key获得value的值

[if !supportLists]1.10 [endif]10_JDBC的CRUD操作之删除操作

图片 35

@Test

图片 36

/**

图片 37

*删除操作的代码完成

7.5.3 获得三番五次

 */

图片 38

public void demo3(){

Connection conn = null;

7.5.4 加载配置文件:Properties对象(可选)

Statement stmt = null;

对应properties文件管理,开垦中也会采纳Properties对象举办。在v3版本中大家将使用加载properties文件获得流,然后使用Properties对象开始展览处理

try{

图片 39

//注册驱动:

图片 40

Class.forName("com.mysql.jdbc.Driver");

图片 41

//得到再三再四:

7.6 实现

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

7.6.1 模板

//创设实践SQL语句对象:

图片 42

stmt = conn.createStatement();

图片 43

//编写SQL:

7.6.2 添加:insert into

String sql = "delete from user where id = 5";

图片 44

//执行SQL:

7.6.3 更新:update...set

int num = stmt.executeUpdate(sql);

图片 45

if(num > 0){

图片 46

System.out.println("删除用户成功!!!");

7.6.4 删除:delete

}

图片 47

}catch(Exception e){

7.6.5 通过ID查询

e.printStackTrace();

图片 48

}finally{

四、JDBC连接池

//财富自由:

1、案例分析

if(stmt != null){

事实上支出中“获得三番五次”或“释放能源”是非常消耗系统能源的五个进程,为了消除此类品质难题,经常情形我们接纳连接池本事,来共享连接Connection

try {

2、连接池概述

stmt.close();

2.1 概念

} catch (SQLException e) {

用池来治本Connection,那样能够重复使用Connection。有了池,所以大家就绝不本身来创设Connection,而是经过池来获得Connection对象。当使用完Connection后,调用Connection的close()方法也不会真正关闭Connection,而是把Connection"归还"给池。池就能够再使用这些Connection对象了。

e.printStackTrace();

图片 49

}

2.2 规范

stmt = null;

java为数据库连接池提供了公私的接口:javax.sql.DataSource,各种厂家供给让谐和的连接池完毕那些接口。这样应用程序才足以方便的切换分化厂家的连接池!

}

普及的连接池:DBCP、C3P0

if(conn != null){

3、自定义连接池

try {

3.1 案例深入分析

conn.close();

我们编辑自定义连接池,必要产生一下步骤

} catch (SQLException e) {

3.1.1 创立连接池完结(数据源),并促成接口javax.sql.DataSource。因为大家只利用该接口中getConnection()方法,简化本案例,大家将和谐提供情势1,而从不兑现接口

e.printStackTrace();

3.1.2 提供二个会见,用于存放连接,因为移除/增添操作过多,所以采用LinkedList

}

3.1.3 本案例在静态代码块中,为连接池开头化3个一而再

conn = null;

3.1.4 之后先后一旦必要连接,调用实现类的getConnection(),本办法将从连接池(容器List)获得接二连三。为了确定保障当前连年只可以提要求二个线程使用,所以大家将一而再先从连接池中移除

}

3.1.5 当用户采纳完连接,释放能源时,不奉行close()方法,而是将接连加多到连接池中

}

3.2 案例完结

}

图片 50

[if !supportLists]1.11 [endif]11_JDBC的CRUD操作之查询操作

3.2.1 提供容器及起先化

@Test

图片 51

/**

3.2.2 得到再而三

*询问多条记下

图片 52

 */

图片 53

public void demo4(){

3.2.3 归还连接

Connection conn = null;

图片 54

Statement stmt = null;

3.2.4 测试使用

ResultSet rs = null;

为了体现连接池优势,大家将动用多线程并发访问,使同三个老是在不相同的时刻,被分裂的线程使用

try{

图片 55

//注册驱动

图片 56

Class.forName("com.mysql.jdbc.Driver");

3.3 自定义连接池:方法进步

//获得一而再

3.3.1 需求

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

自定义连接池中留存严重难点,用户调用getConnection()获得几次三番后,必须利用release()方法开始展览延续的偿还,即使用户调用conn.close()将连接真正的假释,连接池准将面世无连接可用。

//实践操作

此刻我们愿意,即便用户调用了close()方法,连接仍归还给连接池。close()方法原有职能释放财富,期望作用:将近些日子三番五次归还连接池。表达close()方法未有大家愿意的机能,我们将对close()方法实行抓牢,从而达成将连接归还给连接池的功用

//成立实施SQL语句的靶子:

3.3.2 方法提升总计

stmt = conn.createStatement();

<1>承接,子类承继父类,将父类的方法开始展览腹复写,从而举行抓实

//编写SQL:

   使用前提:必须有父类,且存在继续关系

String sql = "select * from user";

<2>装饰者设计形式,此设计情势专门用来进步方法

//执行SQL:

   使用前提:必须有接口

rs = stmt.executeQuery(sql);

   缺点:须求将接口的有着办法都达成

//遍历结果集:

<3>动态代理:在运营时动态的创办代理类,完结抓实际操作作。与装饰者相似

while(rs.next()){

   使用前提:必须有接口

System.out.println(rs.getInt("id") " " rs.getString("username") " " rs.getString("password"));

   难点:供给反射本事

}

<4>字节码巩固,运营时创建目标类子类,从而进行坚实

}catch(Exception e){

   常见第三方框架:cglib、javassist等

e.printStackTrace();

3.3.3 装饰者设计形式

}finally{

设计形式:特地为焚薮而田一类标题,而编写的固定格式的代码。

//财富自由:

装饰者固定结构:接口A,已知达成类C,须要装饰者创设代理类B

if(rs != null){

<1>创建类B,并贯彻接口A

try {

<2>提供类B的构造方法,参数类型为A,用于接收A接口的别的达成类(C)

rs.close();

<3>给类B加多类型为A成员变量,用于存放A接口的别的完毕类

} catch (SQLException e) {

<4>巩固需求的点子

e.printStackTrace();

<5>达成无需巩固的不二秘技,方法体重调用成员变量存放的别的完毕类对应的方法

}

图片 57

rs = null;

3.3.4 实现

}

3.3.4.1 装饰类

if(stmt != null){

图片 58

try {

图片 59

stmt.close();

3.3.4.2 使用装饰者(包装类)

} catch (SQLException e) {

将由DriverManager创立的连日,使用装饰类包装一下,然后增加到连接池中,构造方法军长容器pool传递进入,方便连接的清偿

e.printStackTrace();

图片 60

}

3.3.4.3 使用连接

stmt = null;

图片 61

}

4、C3P0连接池

if(conn != null){

C3P0是开源无需付费的连接池,近年来利用它的开源项目有:Spring、Hibernate等。使用第三方工具需求导入jar包,C3P0使用时还要求丰富配置文件c3p0-config.xml

try {

4.1 导入jar包

conn.close();

咱俩使用的0.9.2版本,供给导入2个jar包

} catch (SQLException e) {

图片 62

e.printStackTrace();

4.2 配置文件

}

<1>配置文件名称:c3p0-config.xml(固定)

conn = null;

<2>配置文件地点:src(类路线)

}

<3>配置文件内容:命名配置

}

图片 63

}

铺排文件内容:暗许配置

[if !supportLists]1.12 [endif]12_JDBC的工具类的收取(写)

图片 64

[if !supportLists]Ø [endif]小结一下抽取的标准化:把一样的操作抽到四个办法里,能够重复使用。

图片 65

有关JDBC大家能够抽出:加载驱动、获取连接、释放财富那三有的的代码。

4.3 常见配置项

/**

图片 66

* JDBC的工具类

图片 67

 * @author  itheima

4.4 编写工具类

 */

C3P0提供基本工具类:ComboPooledDataSource,如若要动用连接池,必须创建该类的实例对象。

public class JDBCUtils {

图片 68

private static final String driverClassName;

图片 69

private static final String url;

图片 70

private static final String username;

5、DBCP连接池

private static final String password;

DBCP也是贰个开源的连接池,是Apache Common成员之一,在厂家费用中也正如常见,tomcat内置的连接池

static{

5.1 导入jar包

driverClassName="com.mysql.jdbc.Driver";

图片 71

url="jdbc:mysql:///web_test3";

5.2 配置文件

username="root";

<1>配置文件名称:*.properties

password="abc";

<2>配置文件地方:大肆,提议src(classpath/类路线)

}

<3>配置文件内容:properties不能够编写中文,不辅助在STS中期维修改,必须运用记事本修改内容,不然普通话注释就乱码了

/**

图片 72

*登记驱动的措施

5.3 常见配置项

 */

图片 73

public static void loadDriver(){

图片 74

try {

5.4 编写工具类

Class.forName(driverClassName);

图片 75

} catch (ClassNotFoundException e) {

图片 76

e.printStackTrace();

五、使用DBUtils增加和删除改查的操作

}

1、案例剖判

}

如若只行使JDBC进行支付,大家会发觉冗余代码过多,为了简化JDBC开垦,大家将应用apache commons组件三个成员:DEUtils。

/**

DBUtils就是JDBC的简化开辟工具包。必要采取才具:连接池(获得一连),SQL语句都不曾少

*收获接二连三的法门

2、案例相关文化

 */

2.1、JavaBean组件

public static Connection getConnection(){

javaBean就是贰个类,在开拓中常用于封装数据。具备如下特点

Connection conn = null;

<1>供给达成接口:java.io.Serializable,常常偷懒省略了。

try{

<2>提供个人字段:private类型 字段名;

//将使得一并注册:

<3>提供getter/setter方法

loadDriver();

<4>提供无参构造

//获得延续

图片 77

conn = DriverManager.getConnection(url,username, password);

图片 78

}catch(Exception e){

3、DBUtils完成CRUD

e.printStackTrace();

3.1 概述

}

DBUtils是java编制程序中的数据库操作实用工具,小巧简单实用

return conn;

DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码

}

DBUtils四个基本功能介绍

/**

<1>QueryRunner中提供对sql语句操作的API

*获释财富的艺术

<2>ResultSetHandler接口,用于定义select操作后,怎么着封装结果集

 */

<3>DBUtils类,它就是一工具类,定义了关闭资源与事务管理的不二等秘书籍

public static void release(Statement stmt,Connection conn){

3.2 QueryRunner核心类

if(stmt != null){

<1>QueryRunner(DataSource ds),提供数据源(连接池),DBUtils底层自动尊崇连接connection

try {

<2>update(String sql,Object...params),推行更新数据

stmt.close();

<3>query(String sql,ResultSetHandler<T>rsh,Object...params),施行查询

} catch (SQLException e) {

3.3 ResultSetHandler结果集管理类

e.printStackTrace();

图片 79图片 80

}

3.4 DBUtils工具类

stmt = null;

closeQuietly(Connection conn) 关闭连接,就算有不行,try后不抛

}

commitAndCloseQuietly(Connection conn) 提交并关闭连接

if(conn != null){

rollbackAndCloseQuietly(Connection conn) 回滚并关闭连接

try {

3.5 实现

conn.close();

3.5.1 添加

} catch (SQLException e) {

图片 81

e.printStackTrace();

图片 82

}

3.5.2 更新

conn = null;

图片 83

}

3.5.3 删除

}

图片 84图片 85

public static void release(ResultSet rs,Statement stmt,Connection conn){

3.5.4 通过id查询

//能源自由:

图片 86

if(rs != null){

3.5.5 查询全数

try {

图片 87

rs.close();

图片 88

} catch (SQLException e) {

3.5.6 总记录数

e.printStackTrace();

图片 89

}

rs = null;

}

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}

测试工具类

@Test

/**

*查询操作:使用工具类

 */

public void demo1(){

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try{

//获得一连:

conn = JDBCUtils.getConnection();

// 创制推行SQL语句的对象:

stmt = conn.createStatement();

//编写SQL:

String sql = "select * from user";

//实践查询:

rs = stmt.executeQuery(sql);

//遍历结果集:

while(rs.next()){

System.out.println(rs.getInt("id") " " rs.getString("username") " " rs.getString("password"));

}

}catch(Exception e){

e.printStackTrace();

}finally{

//释放能源:

JDBCUtils.release(rs, stmt, conn);

}

}

[if !supportLists]1.13 [endif]13_JDBC的配备新闻提取到陈设文件

[if !supportLists]Ø [endif]怎样定义配置文件以及加载配置文件中的音信?

概念配置文件:

取得配置文件中的消息:

[if !supportLists]1.14 [endif]14_JDBC的SQL注入漏洞(SQL演示)

[if !supportLists]Ø [endif]如何是sql注入漏洞?

在大家的网址中必定会有记名的操作,用户之所以能登入成功,分明是由此用户名和对应的密码去数据库中能找到相应的一条数据,假如有些人不领悟密码,只透过输入用户名就能够从数据库中找到一条对应的数目,那么那就叫做sql注入漏洞。

简单说:

经过表单或分界面输入一些SQL字符串,能达到服务器实施,抵达违法操作的目标.

健康的为主登陆流程代码: 

sql注入代码演示:

输入用户名

[if !supportLists]n [endif]aaa’ or ‘1=1密码任性

[if !supportLists]n [endif]aaa’ -- 密码任性  注意:--后边有空格

SQL情状示范:

SELECT * FROM USER WHERE username='aaa' AND PASSWORD='123'

SELECT * FROM USER WHERE username='aaa' OR '1=1' AND PASSWORD='wrwrw'

SELECT * FROM USER WHERE username='aaa'-- ' AND PASSWORD='wrwrw'

代码参见:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java

[if !supportLists]1.15 [endif]15_JDBC的SQL注入漏洞剖析及缓和

[if !supportLists]Ø [endif]sql注入漏洞的缘由是哪些?

[if !supportLists]Ø [endif]怎么着缓和sql注入的纰漏?

[if !supportLists]1、 [endif]由来:重倘诺用户输入了sql中分明的第一字,导致大家的sql语句的剖断标准发出了变通。

利用Statement对象来举办一个sql语句是那样的:

resultSet=statement.executeQuery("select * from user where username='" username "' and password='" password "';");

   我们把用户输入的内容放到上面的sql语句对应的变量处:

or前边的一有的判断创立就能够查到结果。

[if !supportLists]2、 [endif]化解sql注入的狐狸尾巴:使用PreparedStatement对象而不是Statement对象。

PreparedStatement有三个预编写翻译的历程,那些历程会稳固sql语句的格式,对于变量供给是用?来占位,那么传递过来的数码就是带有了sql关键字也不会作为重要字来识别。

public class UserDao {

public boolean login(String username,String password){

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

//定义一个变量:

boolean flag = false;

try{

//获得接二连三:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "select * from user where username = ? and password = ?";

//预编译SQL

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, username);

pstmt.setString(2, password);

//执行SQL语句:

rs = pstmt.executeQuery();//没有须求传入SQL

if(rs.next()){

//表明依照用户名和密码能够查询到那条记下

flag = true;

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(rs, pstmt, conn);

}

return flag;

}

代码参见:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java

[if !supportLists]1.16 [endif]16_JDBC的CRUD操作之PreparedStatement保存操作(写)

@Test

/**

*封存操作

 */

public void demo1(){

Connection conn = null;

PreparedStatement pstmt = null;

try{

//获得接二连三:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "insert into user values (null,?,?,?,?)";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, "eee");

pstmt.setString(2, "abc");

pstmt.setString(3, "旺财");

pstmt.setInt(4, 32);

//执行SQL

int num = pstmt.executeUpdate();//不传SQL

if(num > 0){

System.out.println("保存成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

用jdbc连接数据库并简单执行SQL语句,JDBC的连接mySql的基本知识。JDBCUtils.release(pstmt, conn);

}

}

[if !supportLists]1.17 [endif]17_JDBC的CRUD操作之PreparedStatement修改操作

@Test

/**

*修改操作

 */

public void demo2(){

Connection conn = null;

PreparedStatement pstmt = null;

try{

//获得一连:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, "abc");//设置第贰个?的值

pstmt.setString(2, "1234");

pstmt.setString(3, "旺旺");

pstmt.setInt(4, 23);

pstmt.setInt(5, 4);

//执行SQL:

int num = pstmt.executeUpdate();

if(num > 0){

System.out.println("修改成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

}

[if !supportLists]1.18 [endif]18_JDBC的CRUD操作之PreparedStatement删除操作

@Test

/**

*除去操作

 */

public void demo3(){

Connection conn = null;

PreparedStatement pstmt  = null;

try{

//获得连续:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "delete from user where id = ?";

//预编译SQL

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setInt(1, 4);

//执行SQL:

int num = pstmt.executeUpdate();

if(num > 0){

System.out.println("删除成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

}

[if !supportLists]1.19 [endif]19_JDBC的CRUD操作之PreparedStatement查询操作

@Test

/**

*查询操作

 */

public void demo4(){

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try{

//获得再而三:

conn = JDBCUtils.getConnection();

//编写SQL:

String sql = "select * from user";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

//执行SQL:

rs = pstmt.executeQuery();

//遍历结果集:

while(rs.next()){

System.out.println(rs.getInt("id") " " rs.getString("username") " " rs.getString("password") " " rs.getString("nickname"));

}

}用jdbc连接数据库并简单执行SQL语句,JDBC的连接mySql的基本知识。catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(rs, pstmt, conn);

}

}

[if !supportLists]1.20 [endif]20_JDBC的批管理操作

批管理:一堆SQL一齐实践

@Test

/**

*批管理基本操作

 */

public void demo1(){

Connection conn = null;

Statement stmt = null;

try{

//得到连续:

conn = JDBCUtils.getConnection();

//创制实施批管理指标:

stmt = conn.createStatement();

//编写一群SQL语句:

String sql1 = "create database test1";

String sql2 = "use test1";

String sql3 = "create table user(id int primary key auto_increment,name varchar(20))";

String sql4 = "insert into user values (null,'aaa')";

String sql5 = "insert into user values (null,'bbb')";

String sql6 = "insert into user values (null,'ccc')";

String sql7 = "update user set name = 'mmm' where id = 2";

String sql8 = "delete from user where id = 1";

//增添到批管理

stmt.addBatch(sql1);

stmt.addBatch(sql2);

stmt.addBatch(sql3);

stmt.addBatch(sql4);

stmt.addBatch(sql5);

stmt.addBatch(sql6);

stmt.addBatch(sql7);

stmt.addBatch(sql8);

//试行批管理:

stmt.executeBatch();

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(stmt, conn);

}

}

批量布置(使用PreparedStatement)

@Test

/**

*批量陈设记录:

*亟待在url前边拼接二个参数就可以,效用高

         ?rewriteBatchedStatements=true

 */

public void demo2(){

//记录早先时间:

long begin = System.currentTimeMillis();

Connection conn = null;

PreparedStatement pstmt = null;

try{

//获得一连:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "insert into user values (null,?)";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

for(int i=1;i<=10000;i ){

pstmt.setString(1, "name" i);

//增多到批管理

pstmt.addBatch();

//注意难点:

//实行批处理

if(i % 1000 == 0){

//推行批管理:

pstmt.executeBatch();

//清空批管理:

pstmt.clearBatch();

}

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

long end = System.currentTimeMillis();

System.out.println((end-begin));

}

1.21总结:

演说怎样是JDBC以及为什么要运用JDBC

单独实现使用JDBC焦点API对数据库表记录的CRUD操作(体贴)

成就JDBC工具类的收取与改正(入眼)

演说怎么着是SQL注入漏洞并付诸化解措施

单独实现使用JDBC的预编写翻译对象开始展览CRUD操作(重视)

JDBC的批管理操作

本文由澳门新萄京官方网站发布于数据库网络,转载请注明出处:用jdbc连接数据库并简单执行SQL语句,JDBC的连接

关键词: