说明
越来越晕了,教程和代码示范来自黑马程序员。用了再看吧。
JDBC
JDBC(Java数据库连接的接口)用于统一java代码操作各种数据库。(需要实现类,是数据库厂商提供jar包完成)。 步骤为,导入jar包(可以使用idea的右键添加到库),注册驱动,获取连接对象,定义sql,获取对象,执行语句,处理结果,释放资源。 Class.forName("com.mysql.jdbc.Driver");Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); String sql = "update account set balance = 2000 where id = 1";Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(sql);System.out.println(count);stmt.close();conn.close(); DriverManager :驱动管理对象,Connection :数据库连接对象,Statement :执行sql的对象,ResultSet :结果集对象,Preparedstatement :执行sql的对象 com.mysql.jdbc.Driver类中的静态代码块,执行了注册驱动的操作(使用哪个数据库驱动jar(mysql5以后可以省略,在META-INF.service.java.sql.Driver中自动注册))。 DriverManager对象中静态方法getConnection使用格式如:jdbc:mysql://ip:端口/数据库名。(本地地址3306可以省略ip和端口)。 Connection对象中获取对象方法:createStatement( ),preparedStatement(sql),事务相关:开启: setAutoCommit(boolean autoCommit) ,提交: commit(),回滚: rollback() Statement对象,execute方法(执行任意sql),executeUpdate(执行DML语句(insert,update,delete),DDL语句(create,alter,drop)),返回影响行数(DML有)判断是否成功。executeQuery语句,执行DQL语句(select)。 实例代码:外部的变量,trycatchfinally格式,释放等。 ResultSet结果集对象,作为executeQuery的返回值,封装查询结果,其中的next方法向下移动游标,getXxx获取数据(某一列,Xxx为数据类型,可传入列编号[编号]和列名称)。一般使用while循环判断并执行。 定义抽取JDBC工具类(见代码下),用于简化代码,添加配置文件写入信息,通过静态代码块(只需要读取一次)获取properties配置信息,通过类加载器动态获取绝对路径。
代码语言:javascript复制 1 package cn.itcast.util;
2
3 import java.io.FileReader;
4 import java.io.IOException;
5 import java.net.URL;
6 import java.sql.*;
7 import java.util.Properties;
8
9 /**
10 * JDBC工具类
11 */
12 public class JDBCUtils {
13 private static String url;
14 private static String user;
15 private static String password;
16 private static String driver;
17 /**
18 * 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
19 */
20 static{
21 //读取资源文件,获取值。
22
23 try {
24 //1. 创建Properties集合类。
25 Properties pro = new Properties();
26
27 //获取src路径下的文件的方式--->ClassLoader 类加载器
28 ClassLoader classLoader = JDBCUtils.class.getClassLoader();
29 URL res = classLoader.getResource("jdbc.properties");
30 String path = res.getPath();
31 // System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
32 //2. 加载文件
33 // pro.load(new FileReader("D:\IdeaProjects\itcast\day04_jdbc\src\jdbc.properties"));
34 pro.load(new FileReader(path));
35
36 //3. 获取数据,赋值
37 url = pro.getProperty("url");
38 user = pro.getProperty("user");
39 password = pro.getProperty("password");
40 driver = pro.getProperty("driver");
41 //4. 注册驱动
42 Class.forName(driver);
43 } catch (IOException e) {
44 e.printStackTrace();
45 } catch (ClassNotFoundException e) {
46 e.printStackTrace();
47 }
48 }
49
50
51 /**
52 * 获取连接
53 * @return 连接对象
54 */
55 public static Connection getConnection() throws SQLException {
56
57 return DriverManager.getConnection(url, user, password);
58 }
59
60 /**
61 * 释放资源
62 * @param stmt
63 * @param conn
64 */
65 public static void close(Statement stmt,Connection conn){
66 if( stmt != null){
67 try {
68 stmt.close();
69 } catch (SQLException e) {
70 e.printStackTrace();
71 }
72 }
73
74 if( conn != null){
75 try {
76 conn.close();
77 } catch (SQLException e) {
78 e.printStackTrace();
79 }
80 }
81 }
82
83
84 /**
85 * 释放资源
86 * @param stmt
87 * @param conn
88 */
89 public static void close(ResultSet rs,Statement stmt, Connection conn){
90 if( rs != null){
91 try {
92 rs.close();
93 } catch (SQLException e) {
94 e.printStackTrace();
95 }
96 }
97
98 if( stmt != null){
99 try {
100 stmt.close();
101 } catch (SQLException e) {
102 e.printStackTrace();
103 }
104 }
105
106 if( conn != null){
107 try {
108 conn.close();
109 } catch (SQLException e) {
110 e.printStackTrace();
111 }
112 }
113 }
114
115 }
SQL注入
sql注入问题:普通的字符被当做语句执行,导致系统被通过等安全问题(如密码为:a' ='a' or 'a' ='a)。使用PreparedStatement对象处理,参数使用占位符替代(?),防止注入。 使用如下:即可。适合增删改查,效率更高。
代码语言:javascript复制 1 package cn.itcast.jdbc;
2
3 import cn.itcast.util.JDBCUtils;
4
5 import java.sql.*;
6 import java.util.Scanner;
7
8 /**
9 * 练习:
10 * * 需求:
11 * 1. 通过键盘录入用户名和密码
12 * 2. 判断用户是否登录成功
13 */
14 public class JDBCDemo9 {
15
16 public static void main(String[] args) {
17 //1.键盘录入,接受用户名和密码
18 Scanner sc = new Scanner(System.in);
19 System.out.println("请输入用户名:");
20 String username = sc.nextLine();
21 System.out.println("请输入密码:");
22 String password = sc.nextLine();
23 //2.调用方法
24 boolean flag = new JDBCDemo9().login2(username, password);
25 //3.判断结果,输出不同语句
26 if(flag){
27 //登录成功
28 System.out.println("登录成功!");
29 }else{
30 System.out.println("用户名或密码错误!");
31 }
32
33
34 }
35
36
37
38 /**
39 * 登录方法
40 */
41 public boolean login(String username ,String password){
42 if(username == null || password == null){
43 return false;
44 }
45 //连接数据库判断是否登录成功
46 Connection conn = null;
47 Statement stmt = null;
48 ResultSet rs = null;
49 //1.获取连接
50 try {
51 conn = JDBCUtils.getConnection();
52 //2.定义sql
53 String sql = "select * from user where username = '" username "' and password = '" password "' ";
54 System.out.println(sql);
55 //3.获取执行sql的对象
56 stmt = conn.createStatement();
57 //4.执行查询
58 rs = stmt.executeQuery(sql);
59 //5.判断
60 /* if(rs.next()){//如果有下一行,则返回true
61 return true;
62 }else{
63 return false;
64 }*/
65 return rs.next();//如果有下一行,则返回true
66
67 } catch (SQLException e) {
68 e.printStackTrace();
69 }finally {
70 JDBCUtils.close(rs,stmt,conn);
71 }
72
73
74 return false;
75 }
76
77 /**
78 * 登录方法,使用PreparedStatement实现
79 */
80 public boolean login2(String username ,String password){
81 if(username == null || password == null){
82 return false;
83 }
84 //连接数据库判断是否登录成功
85 Connection conn = null;
86 PreparedStatement pstmt = null;
87 ResultSet rs = null;
88 //1.获取连接
89 try {
90 conn = JDBCUtils.getConnection();
91 //2.定义sql
92 String sql = "select * from user where username = ? and password = ?";
93 //3.获取执行sql的对象
94 pstmt = conn.prepareStatement(sql);
95 //给?赋值
96 pstmt.setString(1,username);
97 pstmt.setString(2,password);
98 //4.执行查询,不需要传递sql
99 rs = pstmt.executeQuery();
100 //5.判断
101 /* if(rs.next()){//如果有下一行,则返回true
102 return true;
103 }else{
104 return false;
105 }*/
106 return rs.next();//如果有下一行,则返回true
107
108 } catch (SQLException e) {
109 e.printStackTrace();
110 }finally {
111 JDBCUtils.close(rs,pstmt,conn);
112 }
113
114
115 return false;
116 }
117
118
119 }
JDBC控制事务:使用Connection对象管理事务。开启(conn.setAutoCommit),提交(conn.commit),回滚(conn.rollback)。(见代码如下)
代码语言:javascript复制 1 package cn.itcast.jdbc;
2
3 import cn.itcast.util.JDBCUtils;
4
5 import java.sql.Connection;
6 import java.sql.PreparedStatement;
7 import java.sql.SQLException;
8
9 /**
10 * 事务操作
11 */
12 public class JDBCDemo10 {
13
14
15 public static void main(String[] args) {
16 Connection conn = null;
17 PreparedStatement pstmt1 = null;
18 PreparedStatement pstmt2 = null;
19
20 try {
21 //1.获取连接
22 conn = JDBCUtils.getConnection();
23 //开启事务
24 conn.setAutoCommit(false);
25
26 //2.定义sql
27 //2.1 张三 - 500
28 String sql1 = "update account set balance = balance - ? where id = ?";
29 //2.2 李四 500
30 String sql2 = "update account set balance = balance ? where id = ?";
31 //3.获取执行sql对象
32 pstmt1 = conn.prepareStatement(sql1);
33 pstmt2 = conn.prepareStatement(sql2);
34 //4. 设置参数
35 pstmt1.setDouble(1,500);
36 pstmt1.setInt(2,1);
37
38 pstmt2.setDouble(1,500);
39 pstmt2.setInt(2,2);
40 //5.执行sql
41 pstmt1.executeUpdate();
42 // 手动制造异常
43 int i = 3/0;
44
45 pstmt2.executeUpdate();
46 //提交事务
47 conn.commit();
48 } catch (Exception e) {
49 //事务回滚
50 try {
51 if(conn != null) {
52 conn.rollback();
53 }
54 } catch (SQLException e1) {
55 e1.printStackTrace();
56 }
57 e.printStackTrace();
58 }finally {
59 JDBCUtils.close(pstmt1,conn);
60 JDBCUtils.close(pstmt2,null);
61 }
62
63
64 }
65
66 }
数据库连接池
数据库连接池,解决连接和释放的效率低下问题(从容器(不是底层系统)中获取连接和释放)。 DateSource(sql下)接口,对应数据库的连接池,getConnection获取数据库连接对象。连接池技术如C3P0、Druid。归还连接:Connection.close不变。 导入对应的技术jar包,定义配置文件(c3p0.properties/c3p0-config.xml)在src目录下(定义连接参数,初始化数量),创建对象ComboPooledDateSource(传入参数或使用默认参数),然后获取连接等,相同(代码如下)。
代码语言:javascript复制 1 package cn.itcast.datasource.c3p0;
2
3 import com.mchange.v2.c3p0.ComboPooledDataSource;
4
5 import javax.sql.DataSource;
6 import java.sql.Connection;
7 import java.sql.SQLException;
8
9 /**
10 * c3p0演示
11 */
12 public class C3P0Demo2 {
13
14 public static void main(String[] args) throws SQLException {
15 /* //1. 获取DataSource,使用默认配置
16 DataSource ds = new ComboPooledDataSource();
17
18 //2.获取连接
19
20 for (int i = 1; i <= 11 ; i ) {
21 Connection conn = ds.getConnection();
22 System.out.println(i ":" conn);
23
24 if(i == 5){
25 conn.close();//归还连接到连接池中
26 }
27 }*/
28
29 //testNamedConfig();
30
31 }
32
33
34 public static void testNamedConfig() throws SQLException {
35 // 1.1 获取DataSource,使用指定名称配置
36 DataSource ds = new ComboPooledDataSource("otherc3p0");
37 //2.获取连接
38 for (int i = 1; i <= 10 ; i ) {
39 Connection conn = ds.getConnection();
40 System.out.println(i ":" conn);
41 }
42 }
43
44 }
Druid使用DruidDataSourceFactory创建对象,使用createDataSource获取连接对象。定义工具类,写好静态代码块,方便使用。(代码如下,),对应使用的配置文件为druid.properties
代码语言:javascript复制 1 package cn.itcast.datasource.druid;
2
3 import cn.itcast.utils.JDBCUtils;
4
5 import java.sql.Connection;
6 import java.sql.PreparedStatement;
7 import java.sql.ResultSet;
8 import java.sql.SQLException;
9
10 /**
11 * 使用新的工具类
12 */
13 public class DruidDemo2 {
14
15 public static void main(String[] args) {
16 /*
17 * 完成添加操作:给account表添加一条记录
18 */
19 Connection conn = null;
20 PreparedStatement pstmt = null;
21 try {
22 //1.获取连接
23 conn = JDBCUtils.getConnection();
24 //2.定义sql
25 String sql = "insert into account values(null,?,?)";
26 //3.获取pstmt对象
27 pstmt = conn.prepareStatement(sql);
28 //4.给?赋值
29 pstmt.setString(1,"王五");
30 pstmt.setDouble(2,3000);
31 //5.执行sql
32 int count = pstmt.executeUpdate();
33 System.out.println(count);
34 } catch (SQLException e) {
35 e.printStackTrace();
36 }finally {
37 //6. 释放资源
38 JDBCUtils.close(pstmt,conn);
39 }
40 }
41
42 }
工具类
代码语言:javascript复制 1 package cn.itcast.utils;
2
3 import com.alibaba.druid.pool.DruidDataSourceFactory;
4
5 import javax.sql.DataSource;
6 import java.io.IOException;
7 import java.sql.Connection;
8 import java.sql.ResultSet;
9 import java.sql.SQLException;
10 import java.sql.Statement;
11 import java.util.Properties;
12
13 /**
14 * Druid连接池的工具类
15 */
16 public class JDBCUtils {
17
18 //1.定义成员变量 DataSource
19 private static DataSource ds ;
20
21 static{
22 try {
23 //1.加载配置文件
24 Properties pro = new Properties();
25 pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
26 //2.获取DataSource
27 ds = DruidDataSourceFactory.createDataSource(pro);
28 } catch (IOException e) {
29 e.printStackTrace();
30 } catch (Exception e) {
31 e.printStackTrace();
32 }
33 }
34
35 /**
36 * 获取连接
37 */
38 public static Connection getConnection() throws SQLException {
39 return ds.getConnection();
40 }
41
42 /**
43 * 释放资源
44 */
45 public static void close(Statement stmt,Connection conn){
46 /* if(stmt != null){
47 try {
48 stmt.close();
49 } catch (SQLException e) {
50 e.printStackTrace();
51 }
52 }
53
54 if(conn != null){
55 try {
56 conn.close();//归还连接
57 } catch (SQLException e) {
58 e.printStackTrace();
59 }
60 }*/
61
62 close(null,stmt,conn);
63 }
64
65
66 public static void close(ResultSet rs , Statement stmt, Connection conn){
67
68
69 if(rs != null){
70 try {
71 rs.close();
72 } catch (SQLException e) {
73 e.printStackTrace();
74 }
75 }
76
77
78 if(stmt != null){
79 try {
80 stmt.close();
81 } catch (SQLException e) {
82 e.printStackTrace();
83 }
84 }
85
86 if(conn != null){
87 try {
88 conn.close();//归还连接
89 } catch (SQLException e) {
90 e.printStackTrace();
91 }
92 }
93 }
94
95 /**
96 * 获取连接池方法
97 */
98
99 public static DataSource getDataSource(){
100 return ds;
101 }
102
103 }
Spring JDBC
Spring JDBC(Spring对JDBC的简单封装)。导入jar包,创建JdbcTemplate对象,调用update执行DML,queryForMap封装为map,queryForList封装为list,query封装为JavaBean,queryForObject封装为对象。 (代码)
代码语言:javascript复制 1 package cn.itcast.jdbctemplate;
2
3 import cn.itcast.utils.JDBCUtils;
4 import org.springframework.jdbc.core.JdbcTemplate;
5
6 /**
7 * JdbcTemplate入门
8 */
9 public class JdbcTemplateDemo1 {
10
11 public static void main(String[] args) {
12 //1.导入jar包
13 //2.创建JDBCTemplate对象
14 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
15 //3.调用方法
16 String sql = "update account set balance = 5000 where id = ?";
17 int count = template.update(sql, 3);
18 System.out.println(count);
19 }
20 }
单元测试
代码语言:javascript复制 1 package cn.itcast.jdbctemplate;
2
3 import cn.itcast.domain.Emp;
4 import cn.itcast.utils.JDBCUtils;
5 import org.junit.Test;
6 import org.springframework.jdbc.core.BeanPropertyRowMapper;
7 import org.springframework.jdbc.core.JdbcTemplate;
8 import org.springframework.jdbc.core.RowMapper;
9
10 import java.sql.Date;
11 import java.sql.ResultSet;
12 import java.sql.SQLException;
13 import java.util.List;
14 import java.util.Map;
15
16 public class JdbcTemplateDemo2 {
17
18 //Junit单元测试,可以让方法独立执行
19
20
21 //1. 获取JDBCTemplate对象
22 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
23 /**
24 * 1. 修改1号数据的 salary 为 10000
25 */
26 @Test
27 public void test1(){
28
29 //2. 定义sql
30 String sql = "update emp set salary = 10000 where id = 1001";
31 //3. 执行sql
32 int count = template.update(sql);
33 System.out.println(count);
34 }
35
36 /**
37 * 2. 添加一条记录
38 */
39 @Test
40 public void test2(){
41 String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
42 int count = template.update(sql, 1015, "郭靖", 10);
43 System.out.println(count);
44
45 }
46
47 /**
48 * 3.删除刚才添加的记录
49 */
50 @Test
51 public void test3(){
52 String sql = "delete from emp where id = ?";
53 int count = template.update(sql, 1015);
54 System.out.println(count);
55 }
56
57 /**
58 * 4.查询id为1001的记录,将其封装为Map集合
59 * 注意:这个方法查询的结果集长度只能是1
60 */
61 @Test
62 public void test4(){
63 String sql = "select * from emp where id = ? or id = ?";
64 Map<String, Object> map = template.queryForMap(sql, 1001,1002);
65 System.out.println(map);
66 //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
67
68 }
69
70 /**
71 * 5. 查询所有记录,将其封装为List
72 */
73 @Test
74 public void test5(){
75 String sql = "select * from emp";
76 List<Map<String, Object>> list = template.queryForList(sql);
77
78 for (Map<String, Object> stringObjectMap : list) {
79 System.out.println(stringObjectMap);
80 }
81 }
82
83 /**
84 * 6. 查询所有记录,将其封装为Emp对象的List集合
85 */
86
87 @Test
88 public void test6(){
89 String sql = "select * from emp";
90 List<Emp> list = template.query(sql, new RowMapper<Emp>() {
91
92 @Override
93 public Emp mapRow(ResultSet rs, int i) throws SQLException {
94 Emp emp = new Emp();
95 int id = rs.getInt("id");
96 String ename = rs.getString("ename");
97 int job_id = rs.getInt("job_id");
98 int mgr = rs.getInt("mgr");
99 Date joindate = rs.getDate("joindate");
100 double salary = rs.getDouble("salary");
101 double bonus = rs.getDouble("bonus");
102 int dept_id = rs.getInt("dept_id");
103
104 emp.setId(id);
105 emp.setEname(ename);
106 emp.setJob_id(job_id);
107 emp.setMgr(mgr);
108 emp.setJoindate(joindate);
109 emp.setSalary(salary);
110 emp.setBonus(bonus);
111 emp.setDept_id(dept_id);
112
113 return emp;
114 }
115 });
116
117
118 for (Emp emp : list) {
119 System.out.println(emp);
120 }
121 }
122
123 /**
124 * 6. 查询所有记录,将其封装为Emp对象的List集合
125 */
126
127 @Test
128 public void test6_2(){
129 String sql = "select * from emp";
130 List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
131 for (Emp emp : list) {
132 System.out.println(emp);
133 }
134 }
135
136 /**
137 * 7. 查询总记录数
138 */
139
140 @Test
141 public void test7(){
142 String sql = "select count(id) from emp";
143 Long total = template.queryForObject(sql, Long.class);
144 System.out.println(total);
145 }
146
147 }
附件
代码语言:javascript复制 1 package cn.itcast.domain;
2
3 import java.util.Date;
4
5 public class Emp {
6 private Integer id;
7 private String ename;
8 private Integer job_id;
9 private Integer mgr;
10 private Date joindate;
11 private Double salary;
12 private Double bonus;
13 private Integer dept_id;
14
15
16 public Integer getId() {
17 return id;
18 }
19
20 public void setId(Integer id) {
21 this.id = id;
22 }
23
24 public String getEname() {
25 return ename;
26 }
27
28 public void setEname(String ename) {
29 this.ename = ename;
30 }
31
32 public Integer getJob_id() {
33 return job_id;
34 }
35
36 public void setJob_id(Integer job_id) {
37 this.job_id = job_id;
38 }
39
40 public Integer getMgr() {
41 return mgr;
42 }
43
44 public void setMgr(Integer mgr) {
45 this.mgr = mgr;
46 }
47
48 public Date getJoindate() {
49 return joindate;
50 }
51
52 public void setJoindate(Date joindate) {
53 this.joindate = joindate;
54 }
55
56 public Double getSalary() {
57 return salary;
58 }
59
60 public void setSalary(Double salary) {
61 this.salary = salary;
62 }
63
64 public Double getBonus() {
65 return bonus;
66 }
67
68 public void setBonus(Double bonus) {
69 this.bonus = bonus;
70 }
71
72 public Integer getDept_id() {
73 return dept_id;
74 }
75
76 public void setDept_id(Integer dept_id) {
77 this.dept_id = dept_id;
78 }
79
80 @Override
81 public String toString() {
82 return "Emp{"
83 "id=" id
84 ", ename='" ename '''
85 ", job_id=" job_id
86 ", mgr=" mgr
87 ", joindate=" joindate
88 ", salary=" salary
89 ", bonus=" bonus
90 ", dept_id=" dept_id
91 '}';
92 }
93 }