JDBC学习笔记(内含普通连接和连接池连接和Spring JDBC)
普通连接
1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");//这是新版数据库的操作,5.0以及以下版本为com.mysql.jdbc.Driver
2.获取数据库连接
方法:
DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true","" + "root","1234567");
/*1.方法getConnection("url","user","password");新版的数据库url后面要加上?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true否则数据库会连接失败
2.如果是本机MySQL服务器,并且服务器默认端口是3306,则url可以去掉localhost:3306
3.Connection 数据库连接对象
1.功能:
-
获取执行sql的对象
- Statement creatStatement()
- PreparedStatement PreparedStatement (String sql)
-
管理事务
-
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务,在连接后开启事务
conn = JDBCUtil.getConnection(); conn.setAutoCommit(false);
-
提交事务:commit()在语句与sql相关的语句写完后提交事务conn.commit();
-
回滚事务:rollback()出现异常后事务回滚,在catch里面回滚 conn.rollback()?注意:因为不管什么异常都是在catch里面回滚,所以抓异常的时候最好抓一个大的异常,还有,回滚的时候可能conn=null,所以要先判断conn!=null,再进行事务回滚)
-
-
Statement:执行sql的对象
- 执行sql
- boolean execute(String sql):可以执行任意的sql (了解)
- int executeUpdate(String sql):执行 DML(insert 、update、delete)语句、DDL(create、alter、drop)语句返回影响的行数
- ResultSet executeQuery(String sql):执行DQL(select)语句
- 执行sql
-
ResultSet:结果集对象,封装查询结果
- boolean next():游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,返回false,如果不是则返回true
- getXxx(参数):获取数据
- Xxx代表数据类型
- 参数:
- int:代表列得编号,从1开始 如:getString(1)
- String:代表列名称 如:getDouble(“name”)
- 注意:
- 使用步骤:
- 游标移动下一行
- 判断是否有数据
- 获取数据
- 使用步骤:
-
PreparedStatement:执行sql的对象
- SQL注入问题:在拼接sql时,有一些sql的特殊关键字与字符的拼接,会造成安全性问题
- 输入用户随便,输入密码:a’or’a’='a
- sql:select * from user where username = ‘jhjshedjfah’ and password = a’or’a’='a
- 解决sql注入问题。使用PreparedStatement对象来解决
- 预编译的SQL,使用?作为占位符
- SQL注入问题:在拼接sql时,有一些sql的特殊关键字与字符的拼接,会造成安全性问题
数据库连接池
数据库连接池其实就是一个容器(集合),存放数据库连接的容器
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用完之后归还给容器
好处
- 节约资源
- 用户 访问高效
实现
-
标准接口:DataSource Javax.sql包下的
-
方法
- 获取连接:getConnection()
- 归还连接:Connection.close(),如果连接对象是从连接池中获取的 那么调用Connection.close()方法不是释放资源而是归还给连接池
-
一般我们不去实现它,有数据库厂商去实现
-
C3p0:数据库连接池技术
步骤
1.导入jar包(两个)c3p0-0.9.5.2.jar 和mchange-commons-java-0.2.12.jar
2.定义配置文件
名称:只能是c3p0.properties或者c3p0-config.xml
路径:直接将文件放在src目录下即可
<!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.cj.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/salary?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true</property> <property name="user">root</property> <property name="password">1234567</property> <!-- 连接池参数 --> <!-- 初始化申请的连接数量--> <property name="initialPoolSize">5</property> <!-- 最大的连接数量--> <property name="maxPoolSize">10</property> <!-- 超时时间--> <property name="checkoutTimeout">3000</property> </default-config>
//1.创建数据库连接池对象,默认连接池 DataSource ds = new ComboPooledDataSource(""); //获取连接对象 Connection conn = ds.getConnection();
//1.创建数据库连接池对象,名为otherc3p0的连接池 DataSource ds = new ComboPooledDataSource("otherc3p0");//获取连接对象 Connection conn = ds.getConnection();
-
Druid:数据库连接池实现技术,由阿里巴巴提供的,目前性能很高的一项连接池技术
Properties pro = new Properties(); InputStream in = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(in); DataSource ds = DruidDataSourceFactory.createDataSource(pro); Connection conn = ds.getConnection();
-
Spring JDBC
简介:Spring框架对JDBC的简单封装
步骤:
-
导入jar包
-
创建JdbcTemplate对象,依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
-
调用JdbcTemplate的方法来完成CRUD的操作
-
update():执行DML语句,增删改
-
queryForMap():查询结果集封装成map集合,将列名作为key,将值作为value将这条记录封装为一个map集合
注意:此方法查询的结果集长度只能是1
public void test(){ String sql = "select * from staff where sid =?"; Map<String,Object> map = template.queryForMap(sql,1); System.out.println(map); }
-
queryForList():查询结果将结果集封装为list集合
注意:将每一条记录封装为一个map集合,再将map集合封装到list集合中
public void test2(){ String sql = "select * from staff"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } }
-
query():查询到结果 ,将结果封装为JavaBean对象
query的参数:RowMapper
一般使用BeanPropertyRowMapper实现类,可以完成数据到JavaBean的自动封装
public void test3(){ String sql = "select * from staff"; List<Staff> list = template.query(sql, new RowMapper<Staff>() { @Override public Staff mapRow(ResultSet rs, int i) throws SQLException { Staff staff = new Staff(); int sid = rs.getInt("sid"); String sname = rs.getString("sname"); int did = rs.getInt("did"); String sphone = rs.getString("sphone"); String semail = rs.getString("semail"); int rid = rs.getInt("rid"); String spassword = rs.getString("spassword"); staff.setSid(sid); staff.setSname(sname); staff.setDid(did); staff.setSphone(sphone); staff.setSemail(semail); staff.setRid(rid); staff.setSpassword(spassword); return staff; } }); for (Staff staff : list) { System.out.println(staff); } }
public void test3_2(){//注意,使用该方法时,实体类里面的 命名要与数据库中的命名相统一 String sql = "select * From staff"; List<Staff> list = template.query(sql, new BeanPropertyRowMapper<Staff>(Staff.class)); for (Staff staff : list) { System.out.println(staff); } }
-
queryForObject:查询结果,将结果封装为对象(一般是一些聚合函数)
public void test4(){ String sql = "select count(*) from staff"; Long total = template.queryForObject(sql,Long.class); System.out.println(total); }
-