1、JDBC的概念:
Java数据库连接技术(Java DataBase Connectivity)能实现java程序对各种数据库的访问,由一组使用java语言编写的类和接口(jdbc api)组成,他们位于java.sql以及javax.sql中。
2、JDBC API 使用JDBC访问数据库就要用JDBC API完成3件事:与数据库链接,返送sql语句和处理结果。
Java应用程序可以使用java.sql和javax.sql包中的JDBC APL来链接和操作;
工作的4个重要环节:
(1).DriverManager类:依据数据库的不同,管理JDBC驱动;
(2).Connection接口:负责链接数据库并担任传送数据的任务。
(3).Statement接口:由Connection产生,负责执行SQL语句。
(4).ResultSet接口:负责保存Statement执行后所参数的查询结果。
3、JDBC访问数据库的步骤:
(1)Class.forName(oracle.jdbc.driver.OracleDriver);//加载驱动
(2)Connection conn=DriverManager.getConnection(“jdbc:oracle:thin:@127.0.0.1:1521:orcl”,”scott”,”orcl”);//创建连接
(3).Statement stmt=conn.createStatement();//创建Statement对象
String sql=””;
ResultSet rs= Stmt.executeQuery(sql);
(4)while(rs.next()){int id=rs.getInt(1);
Timestamp time=rs.getTimestamp(“createdate”);}//循环读取结果集
4.资源的释放
Re.close();
Stmt.close();
Conn.close();
5、通过DatasourceFactory和创建database.properties配置文件链接数据库
1.建BaseDao文件,提取建立数据库连接的通用方法
package demo.mysql.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import demo.mysql.util.ConfigManager;
public class BaseDao {
protected Connection conn;
protected PreparedStatement ps;
protected Statement stmt;
protected ResultSet rs;
// 获取数据库链接
public boolean getConnection() {
String driver = ConfigManager.getInstance().getString("jdbc.driver_class");
String url = ConfigManager.getInstance().getString("jdbc.connection.url");
String username = ConfigManager.getInstance().getString("jdbc.connection.username");
String password = ConfigManager.getInstance().getString("jdbc.connection.password");
try {
// (1).Class.forName()加载驱动
Class.forName(driver);
// (2).DriverManager.getConnection(数据库url,用户名,密码);onnection1521
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
public Connection getConnection2(){
try {
//初始话上下文
Context cxt=new InitialContext();
//获取与逻辑名相关联的数据源对象
DataSource ds=(DataSource)cxt.lookup("java:comp/env/jdbc/orcl");
conn=ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
// 增删改
public int executeUpdate(String sql, Object[] params) {
int updateRows = 0;
getConnection();
try {
ps=conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < params.length; i++) {
ps.setObject(i+1, params[i]);
}
updateRows=ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return updateRows;
}
// 查询
public ResultSet executeSQL(String sql, Object[] params) {
try {
getConnection();
ps=conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < params.length; i++) {
ps.setObject(i+1, params[i]);
}
rs=ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
// 关闭资源
public boolean closeResource() {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
if (ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
return true;
}
}
2.创建EmpDao接口
package demo.mysql.dao;
import java.sql.Date;
public interface EmpDao {
/**
* 查询
*/
public void empList();
/**
* 添加
*/
public void add(int empno,String ename,String job,int mgr,Date hireDate,double sal,double comm,int deptno);
/**
* 删除
*/
public void delete(int empno);
/**
* 修改
*/
public void update(int empno,String ename);
}
3.创建EmpDaoImpl实现类:
package demo.mysql.dao.impl;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import demo.mysql.dao.BaseDao;
import demo.mysql.dao.EmpDao;
public class EmpDaoImpl extends BaseDao implements EmpDao {
/**
* 查询
*/
public void empList() {
try {
// (3).创建statement 对象执行sql
String sql = "select * from emp";
Object[] params = {};
ResultSet rs = this.executeSQL(sql, params);
// 处理结果集
while (rs.next()) {
int empno = rs.getInt("EMPNO");
String ename = rs.getString("ENAME");
String job = rs.getString("JOB");
int mgr = rs.getInt("MGR");
Timestamp time = rs.getTimestamp("HIREDATE");
int sal = rs.getInt("SAL");
double comm = rs.getInt("COMM");
int deptno = rs.getInt("DEPTNO");
System.out.println(empno + "\t" + ename + "\t" + job + "\t"
+ mgr + "\t" + time + "\t" + sal + "\t" + comm + "\t"
+ deptno);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeResource();
}
}
/**
* 添加
*/
public void add(int empno,String ename,String job,int mgr,Date hireDate,double sal,double comm,int deptno){
try {
//(3).创建statement 对象执行sql
String sql="insert into emp values(?,?,?,?,?,?,?,?)";
Object[] params={empno,ename,job,mgr,new java.sql.Timestamp(hireDate.getTime()),sal,comm,deptno};
int i=this.executeUpdate(sql, params);
if(i>0){
System.out.println("插入新闻成功");
}
}finally{
this.closeResource();
}
}
/**
* 删除
*/
public void delete(int empno){
try {
String sql="delete from emp where empno=?";
Object[] params={empno};
int i=this.executeUpdate(sql, params);
if(i>0){
System.out.println("删除信息成功");
}
}finally{
this.closeResource();
}
}
/**
* 修改
*/
public void update(int empno,String ename){
try {
String sql="update emp set ename=? where empno=?";
Object[] params={ename,empno};
int i=this.executeUpdate(sql, params);
if(i>0){
System.out.println("修改信息成功");
}
}finally{
this.closeResource();
}
}
}
3.两种连接数据库的方式
(1)、通过DatasourceFactory连接数据库
package demo.mysql.testByDataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class MysqlDatasourceFactory {
private final String DRIVER = "com.mysql.jdbc.Driver";
/**
* 子类可以修改url、username以及pwd的值
*/
private String url ="jdbc:mysql://192.168.9.223:3306/test_2016?useUnicode=true&characterEncoding=utf-8";
private String username = "root";
private String pwd = "ablejava";
protected Connection openConnection(){
Connection con = null;
try {
//装载数据库驱动
Class.forName(DRIVER);
//建立数据库连接
con = DriverManager.getConnection(url,username,pwd);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
main方法测试类:
package demo.mysql.testByDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
public class Test {
public static void main(String[] args) {
try {
MysqlDatasourceFactory m=new MysqlDatasourceFactory();
System.out.println(m.openConnection());
// 建立连接
Connection conn = m.openConnection();
String sql = "select * from emp";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
int empno = rs.getInt("EMPNO");
String ename = rs.getString("ENAME");
String job = rs.getString("JOB");
int mgr = rs.getInt("MGR");
Timestamp time = rs.getTimestamp("HIREDATE");
int sal = rs.getInt("SAL");
double comm = rs.getInt("COMM");
int deptno = rs.getInt("DEPTNO");
System.out.println(empno + "\t" + ename + "\t" + job + "\t"
+ mgr + "\t" + time + "\t" + sal + "\t" + comm + "\t"
+ deptno);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
(2)、创建database.properties配置文件链接数据库
在src下创建datebase.properties文件;
添加key – value :
oracle:
jdbc.driver_class=oracle.jdbc.driver.OracleDriver;
jdbc.connection.url=jdbc:oracle:thin:@localhost:1521:orcl;
jdbc.connection.username=scott;
jdbc.connection.password=orcl;
mysql:
jdbc.driver_class=com.mysql.jdbc.Driver
jdbc.connection.url=jdbc\:mysql\://192.168.9.223\:3306/test_2016?useUnicode\=true&characterEncoding\=utf-8
jdbc.connection.username=root
jdbc.connection.password=ablejava
设置配置工具类(Class ConfigManager(){})
package demo.mysql.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ConfigManager {
private static ConfigManager configManager;
private static Properties properties;
private ConfigManager(){
String configFile="database.properties";
try {
properties=new Properties();
InputStream in=ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
//读取配置文件
//properties.load(InputStream);读取文件
properties.load(in);
in.close();//将流关闭
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 通过单例模式设置实例化的个数
* @return
*/
public static ConfigManager getInstance(){
if (configManager==null) {
configManager=new ConfigManager();
}
return configManager;
}
/**
* 在database.properties总根据key得到对应的value值
*/
public String getString(String key){
return properties.getProperty(key);
}
}
6.使用ConfigManager()工具类读取数据库
package demo.mysql.testByProperties;
import demo.mysql.dao.EmpDao;
import demo.mysql.dao.impl.EmpDaoImpl;
public class Test {
public static void main(String[] args) {
EmpDao empDao = new EmpDaoImpl();
empDao.empList();
}
}
运行结果:
6、PreparedStatement对象
PreparedStatement接口继承来自Statement接口,它对SQL语句进行了预编译,所以执行速度快于Statement对象,Sql语句具有一个或多个数据参数,这些参数的值在SQL中没指定,可以为每个参数保留一个问号(?)作为占位符,热后用对象赋值。
如果数据类型是日期格式采用:
SetTimestamp(参数位置,new java.sql.Timestamp(new java.util.Date().getTime()));
如果数据类型为Clob类型,则可将其视为String类型那个进行设置。
7.Sql注入: a’ or 1=1 --
8.MVC设计模式概念(三层模式):
1、 表示层
职责:位于最上层,用户能够直接访问,用与显示数据和接收用户数据的数据,为用户提供一种交互式操作界面,一般为web应用程序,以jsp文件,HTML文件为主。
2、业务逻辑层:
职责:提供对业务逻辑处理的封装,通常会定义一些接口,通常放在biz包下。
3、 数据库访问层:
职责:实现对数据的保存和读取操作,数据访问,可以访问数据库,文本文件或xml文挡,通常放在dao包中。
MVC:一般把业务逻辑层和数据访问层称Modle层,把表示层称View层,在V层和M层中间还有Control层。
9、数据源与连接池:
数据源的作用就是获取数据连接,而连接池则是对已经创建好的连接对象进行管理,二者作用不同。
oracle连接数据源的配置步骤:
1. 在tmocat服务器中添加数据库驱动,将oracle14.jar添加到tomcat安装目录的lib文件夹中。
2. 在tomcat服务器中配置。
<Resource name="jdbc/orcl" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="orcl" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl"/>
maxActive:表示处于活动最大连接数量,maxIdle:处于空闲的最大连接数量,maxWait:最大等待时间,-1表示无限等待,单位ms
3. 使用JNDI读取数据源:
JNDI(Java Naming and Directory interface,java命名与目录接口),获取数据源时,javax.naming.context提供了查询jndiResource的接口,通过该对象的lookup()方法,就可以找到之前创建好的数据源。
public Connection getConnection2(){
try {
//初始话上下文
Context cxt=new InitialContext();
//获取与逻辑名相关联的数据源对象
DataSource ds=(DataSource)cxt.lookup("java:comp/env/jdbc/orcl");
conn=ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
8、jsp中的动作标签
<jsp:useBean id=”newService” class=”com.service.newServiceImpl” scop=”page”> scop的取值为:page(默认),request,session,application
<jsp:useBean id=”newsDao” class=”com.impl.newDaoImpl” scop=”page”>
<jsp:setProperty property=”newsDao” name=”newsService” value=”<%=newsDao %>”>
等同于:NewsServiceImpl newsService=new NewsServiceImpl();
NewsDao newsDao=new NewsDaoImpl();
newsService.setNewsDao(newsDao);
jsp页面的包含:
<%@include file="top.jsp" %> 静态包含
<jsp:include page=”url”> 动态包含
静态包含与动态包含的区别:
静态 | 动态 |
<%@include file=”url”> | <jsp:include page=”url”> |
先将页面包含,后执行页面代码,将一个页面的代码复制到另一个页面中 | 先执行页面代码,后将页面包含,即将一个页面的运行结果包含到另外一个页面中 |
被包含的页面内容发生变化时,包含页面也将会被重新编译 | 被包含页面内容发生变化时,包含页面不会重新编译 |
页面的跳转:
<jsp:forward page=”url”> 同转发效果相同
DatasourceFactory
源码下载:https://github.com/ablejava/JDBC