JDBC
JDBC4驱动加载问题
JDK1.6之后JDBC就升级到了JDBC4,只要数据库生产商实现了JDBC4提供的接口,则在连接数据时,不需要显式加载驱动,系统自动加载
mysql驱动从5.1开始支持jdbc4
关于URL语法:jdbc:子协议://地址:端口号/数据库实例名
MySQL:jdbc:mysql://127.0.0.1:3306/test
sqlserver: jdbc:sqlserver://127.0.0.1:1433;databaseName=test
oracle: jdbc:oracle:thin:@127.0.0.1:1521:orcl
JDBC连接数据库:
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载数据库提供商提供的驱动
Class.forName("com.mysql.jdbc.Driver");
//DriverManager.registerDriver(new Driver());
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb", "root", "123456");
//Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?user=root&&password=123456");
System.out.println(conn);
//3.获取处理命令(用于处理SQL语句)
Statement stmt = conn.createStatement();
//4.发送执行sql命令
//boolean f = stmt.execute("create table people(name varchar(16),id int ,sex varchar(8));");
stmt.execute("insert into people values('吴为傻逼',1,'20')");
//5.处理执行结果
//System.out.println(f);
//6.回收资源
stmt.close();
conn.close();
execute,executeUpdate,executeQuery区别?
excute用于执行任何的sql语句,返回布尔类型结果,如果被执行的sql语句为查询相关语句则会有ResultSet产生,从而返回true;其他非查询操作都会返回false
executeUpdate主要用于执行DML语句中的insert,delete,update操作,同时可以执行DDl(建表,建库)相关操作,如果执行DML中增删改操作时会返回操作影响的数据行数,如果是DDL操作则返回0.
JDBC实现增删改查:(Statement为不安全对象,容易产生sql注入)
public class JdbcCrud {
/**
* 向表中添加数据
*/
public void insert(String name, int id, String sex) {
Connection conn = null;
Statement stmt = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb", "root", "123456");
// 创建处理命令
stmt = conn.createStatement();
// 执行sql语句
int i = stmt.executeUpdate("insert into people(name,id,sex) values('" + name + "','" + id + "','" + sex + "')");
//处理结果
if(i > 0)
{
System.out.println("添加成功,影响数据行数:"+i);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(stmt != null) stmt.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//查询所有操作
public void queryAll()
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?user=root&&password=123456");
stmt = conn.createStatement();
//执行查询操作获取结果集
rs = stmt.executeQuery("select * from people");
//取出结果集中的数据
while(rs.next()){
String name = rs.getString("name");
int id = rs.getInt("id");
String sex = rs.getString("sex");
System.out.println(name+"-----"+id+"-----"+sex);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(rs!=null)rs.close();
if(stmt!=null)stmt.close();
if(conn!=null)conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//根据用户id删除指定用户
public void deleteById(int id)
{
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?user=root&&password=123456");
stmt = conn.createStatement();
int i = stmt.executeUpdate("delete from people where id =" + id );
System.out.println("删除成功,影响数据行数:"+i);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(stmt!=null)stmt.close();
if(conn!=null)conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
PreparedStatement(可防止SQL注入)
public class JdbcSafe
{
public void add(String name,int id,String password)
{
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn =
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb", "root", "123456");
ps = conn.prepareStatement("insert
into tbuser(name,id,password) values(?,?,?)");
ps.setString(1, name);
ps.setInt(2, id);
ps.setString(3, password);
int i =ps.executeUpdate();
System.out.println("影响记录行数:"+i);
} catch (ClassNotFoundException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
} catch (SQLException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
}finally{
try {
ps.close();
conn.close();
} catch (SQLException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
}
}
}
JDBC连接封装和配置文件
//配置文件
####mysql connection
info####
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/mydb
user = root
password = 123456
public class DBConnection
{
//声明连接数据库的基本参数
private static
String DRIVER = "com.mysql.jdbc.Driver";
private static
String URL = "jdbc:mysql://127.0.0.1:3306/mydb";
private static
String USER = "root";
private static
String PASSWORD = "123456";
//在静态块中加载驱动,防止反复加载
static{
try {
//获取属性文件
Properties pros =
System.getProperties();
//加载指定属性文件
pros.load(new FileInputStream("src/jdbc.properties"));
DRIVER = pros.getProperty("driver");
URL = pros.getProperty("url");
USER = pros.getProperty("user");
PASSWORD = pros.getProperty("password");
Class.forName(DRIVER);
} catch (ClassNotFoundException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
} catch (FileNotFoundException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
}
}
//封装获取连接方法
public static Connection
getConn()
{
try {
return DriverManager.getConnection(URL,USER,PASSWORD);
} catch (SQLException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
}
return null;
}
//封装资源回收的方法
public static void close(ResultSet rs,Statement stmt,Connection conn)
{
try {
if(rs != null)rs.close();
if(stmt!=null)stmt.close();
if(conn!=null)conn.close();
} catch (SQLException e)
{
// TODO Auto-generated
catch block
e.printStackTrace();
}
}
}
JDBC日期时间类型转换
public void add(String content,Date lasttime) throws SQLException{
Connection conn =
DBConnection.getConn();
PreparedStatement ps = conn.prepareStatement("insert
into daily(content,lasttime) values(?,?)");
ps.setString(1, content);
ps.setTimestamp(2, new Timestamp(lasttime.getTime()));
int i = ps.executeUpdate();
System.out.println(i);
}
public void queryAll() throws SQLException{
Connection conn =
DBConnection.getConn();
PreparedStatement ps = conn.prepareStatement("select
content,submittime,lasttime from daily");
ResultSet rs = ps.executeQuery();
while(rs.next())
{
String content = rs.getString("content");
Date d1 = rs.getTimestamp("submittime");
Date d2 = rs.getTimestamp("lasttime");
System.out.println(content+"--"+d1+"--"+d2);
}
}
简单封装:查询数据库中某个表中的所有数据
public List<Object[]> query() throws SQLException{
PreparedStatement ps =
DBConnection.getConn().prepareStatement("select
* from department limit 0,10");
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
List<Object[]> list = new ArrayList<>();
while(rs.next()){
//每读取到一行记录声明一个数组
Object[] objs = new Object[count];
for (int i =
1; i <= count; i++)
{
//获取列标签名(别名,若不存在则用列名)
String label = rsmd.getColumnLabel(i);
//获取列名称
String cname = rsmd.getColumnName(i);
//获取列数据类型
// int type
= rsmd.getColumnType(i);
// if(type
== java.sql.Types.INTEGER){
// int num =
rs.getInt(label);
// System.out.print(num+"
");
// }else
if(type == java.sql.Types.VARCHAR){
// String
value = rs.getString(label);
// System.out.print(value+"
");
// }
//获取一列数据
Object obj = rs.getObject(label);
//将列数据装入数组中
objs[i-1]
= obj;
}
//将装有多列数据的一行结果装入集合
list.add(objs);
}
return list;
}
JDBC存储过程调用
//不带参数的存储过程调用
Connection conn =
DBConnection.getConn();
CallableStatement cs = conn.prepareCall("{call pro_01}");
//带参数的存储过程调用(分页)
//DTO
public class PageUtils
{
private int currentPage; //当前页
private int pageSize; //每页大小
private String tableName; //表名称
private String selections; //查询列
private String condition; //查询条件
private String sortColumn; //排序列
private String sortType; //排序类型 asc desc
private int totalNum; //总记录数
private int totalPage; //总页码数
private List<Object[]> datas; //当前页数据
public int getCurrentPage()
{
return currentPage;
}
public void setCurrentPage(int currentPage)
{
this.currentPage = currentPage;
}
public int getPageSize()
{
return pageSize;
}
public void setPageSize(int pageSize)
{
this.pageSize = pageSize;
}
public String
getTableName() {
return tableName;
}
public void setTableName(String tableName)
{
this.tableName = tableName;
}
public String
getSelections() {
return selections;
}
public void setSelections(String selections)
{
this.selections = selections;
}
public String
getCondition() {
return condition;
}
public void setCondition(String condition)
{
this.condition = condition;
}
public String
getSortColumn() {
return sortColumn;
}
public void setSortColumn(String sortColumn)
{
this.sortColumn = sortColumn;
}
public String
getSortType() {
return sortType;
}
public void setSortType(String sortType)
{
this.sortType = sortType;
}
public int getTotalNum()
{
return totalNum;
}
public void setTotalNum(int totalNum)
{
this.totalNum = totalNum;
}
public int getTotalPage()
{
return totalPage;
}
public void setTotalPage(int totalPage)
{
this.totalPage = totalPage;
}
public List<Object[]>
getDatas() {
return datas;
}
public void setDatas(List<Object[]> datas)
{
this.datas = datas;
}
}
public PageUtils procPaging(PageUtils pu) throws SQLException{
CallableStatement cs =
getConn().prepareCall("{call sp_paging(?,?,?,?,?,?,?,?,?)}");
cs.setInt(1, pu.getCurrentPage());
cs.setInt(2, pu.getPageSize());
cs.setString(3, pu.getTableName());
cs.setString(4, pu.getSelections());
cs.setString(5, pu.getCondition());
cs.setString(6, pu.getSortColumn());
cs.setString(7, pu.getSortType());
//注册输出参数
cs.registerOutParameter(8,
java.sql.Types.INTEGER);
cs.registerOutParameter(9,
java.sql.Types.INTEGER);
//执行存储过程
cs.execute();
//获取制定位置的输出参数值
int totalNum = cs.getInt(8);
int totalPage = cs.getInt(9);
pu.setTotalNum(totalNum);
pu.setTotalPage(totalPage);
//声明用于存储查询结果的集合
List<Object[]> datas = new ArrayList<>();
//获取查询的结果集
ResultSet rs = cs.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
while(rs.next()){
Object[] obj = new Object[count];
for(int i =
0;i<count;i++){
//获取标签名称(可能是列名称)
String label = rsmd.getColumnLabel(i+1);
Object c = rs.getObject(label);
obj[i]
= c;
}
datas.add(obj);
}
//将查询结果设置到PageUtils中
pu.setDatas(datas);
return pu;
}
DTO:(Data Transfer Object)数据传输对象,用于在前后端(界面,数据库)之间进行数据传递
1.临时存储界面提交的数据,并将数据通过jdbc加入到数据库中(数据持久化)
2.取出数据库表中的数据,临时存储到对象,并运转到界面端展示
public void add(Emp emp) throws SQLException{
String sql = "insert into employee(name,sex,tel,addr,email,zip,depno,birth) values(?,?,?,?,?,?,?,?)";
PreparedStatement ps = getConn().prepareStatement(sql);
ps.setString(1,emp.getName());
ps.setString(2,emp.getSex());
ps.setString(3,emp.getTel());
ps.setString(4,emp.getAddr());
ps.setString(5,emp.getEmail());
ps.setString(6,emp.getZip());
ps.setInt(7, emp.getDepno());
ps.setDate(8, new java.sql.Date(emp.getBirth().getTime()));
int i = ps.executeUpdate();
System.out.println("执行结果:"+i);
}
public List<Emp> findAll() throws SQLException{
List<Emp> list = new ArrayList<>();
String sql = "select num,name,sex,tel,addr,email,zip,depno,birth from employee limit 0,10";
PreparedStatement ps = getConn().prepareStatement(sql);
ResultSet rs = ps.executeQuery();
Emp emp = null;
while(rs.next()){
int num = rs.getInt("num");
String name = rs.getString("name");
String addr = rs.getString("addr");
String email = rs.getString("email");
String sex = rs.getString("sex");
String tel = rs.getString("tel");
String zip = rs.getString("zip");
int depno = rs.getInt("depno");
Date birth = rs.getDate("birth");
emp = new Emp(name, addr, zip, email, tel, sex, birth, depno);
emp.setNum(num);
list.add(emp);
}
return list;
}
分层思想:
视图层
业务逻辑层
数据持久层
DAO:(Data Access Object)数据访问对象,负责对数据库进行CRUD相关的访问操作,内部的每一个方法都是一个对于数据库的原子操作
public class UserDAO extends BaseConn {
PreparedStatement ps;
ResultSet rs;
// 添加操作
public boolean insert(User user) throws SQLException {
ps = getConn().prepareStatement("insert into tbuser(username,password) values(?,?)");
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
int i = ps.executeUpdate();
return i > 0 ? true : false;
}
// 删除操作
public boolean delete(User user) throws SQLException {
ps = getConn().prepareStatement("delete from tbuser where id=?");
ps.setInt(1, user.getId());
int i = ps.executeUpdate();
return i > 0 ? true : false;
}
// 修改操作
public boolean update(User user) throws SQLException {
ps = getConn().prepareStatement("update tbuser set password=? where id=?");
ps.setString(1, user.getPassword());
ps.setInt(2, user.getId());
int i = ps.executeUpdate();
return i > 0 ? true : false;
}
// 查询所有
public List<User> findAll() throws SQLException {
List<User> list = new ArrayList<>();
ps = getConn().prepareStatement("select * from tbuser");
rs = ps.executeQuery();
User user = null;
while(rs.next()){
user = new User(rs.getInt("id"),rs.getString("username"), rs.getString("password"));
list.add(user);
}
return list;
}
// 根据id查询
public User findById(int id) throws SQLException {
ps = getConn().prepareStatement("select * from tbuser where id=?");
ps.setInt(1, id);
rs = ps.executeQuery();
User user = null;
if(rs.next()){
user = new User(id,rs.getString("username"), rs.getString("password"));
}
return user;
}
}
JDBC存储大文件
//存文件
public void insertClob(File file) throws SQLException, IOException{
Connection conn = DBUtils.getConn();
//获取文件字符输入流
FileReader br = new FileReader(file);
PreparedStatement ps = conn.prepareStatement("insert
into tb_clob(fname,content) values(?,?)");
ps.setString(1, file.getName());
ps.setCharacterStream(2,br);
if(ps.executeUpdate()
> 0 ){
System.out.println("写入完成!");
}
ps.close();
br.close();
conn.close();
}
//取出文件
public void selectClob(int id) throws SQLException
{
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement("select
content from tb_clob where id=?");
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if(rs.next()){
String content = rs.getString("content");
// Reader reader = rs.getCharacterStream("content"); //如果需要将数据存储到文件中,则获取字符流
System.out.println(content);
}
}
//存二进制文件
如果向MySQL中存储二进制文件时,数据库的字符集不能设置为GBK,要设置成UTF8
public void insertBlob(File file) throws SQLException, IOException
{
Connection conn = DBUtils.getConn();
//获取文件的字节输入流
FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement("insert
into tb_blob(fname,file) values(?,?)");
ps.setString(1, file.getName());
ps.setBinaryStream(2, fis); //设置二进制流
if(ps.executeUpdate()
> 0){
System.out.println("文件写入完成!");
}
ps.close();
fis.close();
conn.close();
}
//取二进制文件
public void selectBlob(int id,File dir) throws SQLException, IOException{
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement("select
fname,file from tb_blob where id=?");
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if(rs.next()){
//获取文件名
String fname = rs.getString("fname");
//获取文件的二进制流(输入)
InputStream is = rs.getBinaryStream("file");
//将文件名和目录组合为目标文件,并创建输出流
FileOutputStream fos = new FileOutputStream(new File(dir,fname));
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len =
0;
while((len = bis.read(b))
!= -1)
{
bos.write(b,0,len);
}
bos.close();
bis.close();
}
rs.close();
ps.close();
conn.close();
}