JDBC连接数据库
//数据库管理类,获取连接,关闭资源
package com.hui.mysql.utils;
import java.sql.*;
public class DBManager {
private static String className = "com.mysql.jdbc.Driver";
private static String userName = "root" ;
private static String psw = "123456" ;
private static String url = "jdbc:mysql://localhost/mydata" ;
public static Connection getConnection(){
Connection conn = null ;
try {
//加载驱动
Class.forName(className);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//获取连接
conn = DriverManager.getConnection(url,userName,psw);
} catch (SQLException e) {
e.printStackTrace();
}
return conn ;
}
/**
* 关闭资源
* @param conn
* @param stmt
* @param rs
*/
public static void closeResourse(Connection conn , Statement stmt , ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//实例
import java.sql.*;
import com.hui.mysql.utils.DBManager;
public class JDBC {
public static void main(String[] args) {
DBManager dbm = new DBManager();
Connection conn = dbm.getConnection();
PreparedStatement pstm = null ;
try {
pstm = conn.prepareStatement("insert into test values (?,?,?)");//预处理语句
for(int i = 0 ; i < 200 ; i++){
int id = 2000 + i ;
String name = "name" + i ;
String email = "email@00" + i +".com" ;
pstm.setInt(1, id);
pstm.setString(2, name);
pstm.setString(3, email);
pstm.addBatch();
//分批处理
if(i%60 == 0){
pstm.executeBatch();
pstm.clearBatch();
}
}
//注意会有残余未处理的项目
pstm.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
//注意关闭资源
DBManager.closeResourse(conn, pstm, null);
}
}
Java 通过JDBC获得连接以后,得到一个Connection 对象,可以从这个对象获得有关数据库管理系统的各种信息,包括数据库中的各个表,表中的各个列,数据类型,触发器,存储过程等各方面的信息。根据这些信息,JDBC可以访问一个实现事先并不了解的数据库。
获取这些信息的方法都是在DatabaseMetaData类的对象上实现的,而DataBaseMetaData对象是在Connection对象上获得的。
DatabaseMetaData 类中提供了许多方法用于获得数据源的各种信息,通过这些方法可以非常详细的了解数据库的信息:
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
通过Connection对象创建的Statement或PrepareStatement对象,可以设定结果集的类型,可滚动 可更新 参数在ResultSet类中查找
//此处用到工厂模式 Statement和PrepareStatement 都是接口无法实例化对象
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs will be scrollable, will not show changes made by others,
// and will be updatable
//sql中的高级查询语句构建
String username = null ;
String sex = null ;
String edu = null ;
//通过提交的表单获取查询的数据
username = "小明";
sex = "男" ;
edu = "" ;
//连接数据库...
/*
* 方法一
*/
//拼凑查询语句
/*String sql = "select id,username,sex,edu,birthday from employees where 1=1 " ;//注意where 1=1 作用
if(username!=null && !"".equals(username.trim())){
sql = sql + "and username like '%"+username+"%' ";
}
if(sex!=null && !"".equals(sex.trim())){
sql = sql + "and sex = '" + sex + "' ";
}
if(edu!=null && !"".equals(edu.trim())){
sql = sql + "and edu ='"+edu+"' ";
}
System.out.println(sql);*/
/*
* 方法二
*/
if(username == null || "".equals(username)){
username="";
}
if(sex == null || "".equals(sex)){
sex = "" ;
}
if(edu==null || "".equals(edu)){
edu = "" ;
}
String sql = "select id,username,sex,edu,birthday from employees where username like '%"+username+
"%' and sex like '%"+sex+"%' and edu like '%"+edu+"%'";
System.out.println(sql) ;//这种方式中%%相当于查询所有情况除了null
DBCP连接池技术
DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
Junit 单元测试
可以继承 TestCase 也可以:
dbutil是用来查询并以一定方式(list等)获取查询结果的工具类
在一个类(比如dao层实现类)中的保存,更新等一些方法中包含一些多次使用的方法,可以让此类继承一个类,在父类中写方法,子类调用(在视频20dbutil练习)
表单提交要避免重复
第一种:用js代码解决
表单中的自动提交和js代码中的提交会重复,注意!
第二种:在session中添加一个标记变量
在进行save代码操作时进行判断即可,并修改该变量状态
session会过期
Hibernate
当有两个对象同时进行插入(两个线程)时,比如new
Customer A 和 B 如果插入的两个对象没有自己设id 那么会从数据库中取最大id加1,但是两个对象同时取,第二个对象插入时就会报错,id已存在
因此需要合理选择主键生成策略
亮色为代理主键
当没有指针或引用直接或间接到达时,对象才会被销毁
flush是刷新hibernate的数据到数据库中
refresh是刷新数据库中的数据到hibernate中
Dao层的方法是否写成静态的?
做成静态方法的话,完全把 DAO 想成一个工具类了。一般来说工具类是与具体的业务性质无关的,
存放的是一些工具方法,在任何程序中都有可能用到的东西。
做成静态方法的话,让业务层与 DAO 层完全耦合起来了,如果 DAO 在技术更新后需要采用其他的
ORM 工具重新实现的话,这样一来根本就不可能另外再实现一个 DAO 类,只能在原始的 DAO 类中
更改,要么就需要更改业务类中的代码,如果项目很大的话,这个工作量是非常惊人的。
静态 DAO 方法,在事务上下文中会存在问题,没办采用声明式事务进行管理(比如:Spring 中或
者是 EJB 中的),因为声明式事务处理需要采用动态代理方式进行事务上下文的切入,由于不存在
DAO 对象,因此也不存在代理对象,也没办法使用声明式事务,只能手工处理。
如果一个业务逻辑调用多个 DAO 方法的话,在这种事务上下文环境中,如果靠手工处理事务那会是
非常繁锁,而且将事务逻辑侵入到了业务层中。