JDBC
JDBC(Java Database Connectivity)是Java连接数据库的一套规范,用来实现对数据库的操作。
1.JDBC API
1.1 DriverManager类
1.2 Connection接口
1.3 Statement接口
1.4 ResultSet接口
1.5 SQLException类
2.JDBC开发步骤
2.1 executeUpdate()
public class DeleteJdbc {
public static void main ( String[ ] args) throws Exception{
Class. forName ( "com.mysql.jdbc.Driver" ) ;
Connection connection = DriverManager. getConnection ( "jdbc:mysql://localhost:3306/companydb" , "root" , "1234" ) ;
Statement statement = connection. createStatement ( ) ;
int result = statement. executeUpdate ( "delete from t_jobs where job_id = 'H5_mgr';" ) ;
if ( result== 1 ) {
System. out. println ( "删除成功!" ) ;
} else {
System. out. println ( "删除失败!" ) ;
}
statement. close ( ) ;
connection. close ( ) ;
}
2.2 executeQuery()
public class JobsQuery {
public static void main ( String[ ] args) {
Class. forName ( "com.mysql.jdbc.Driver" ) ;
Connection connection = DriverManager. getConnection ( "jdbc:mysql://localhost:3306/product" , "root" , "1234" ) ;
Statement statement = connection. createStatement ( ) ;
ResultSet resultSet = statement. executeQuery ( "select * from t_jobs" ) ;
while ( resultSet. next ( ) ) {
String job_id = resultSet. getString ( "job_id" ) ;
String job_title = resultSet. getString ( "job_title" ) ;
int min_salary = resultSet. getInt ( "min_salary" ) ;
int max_salary = resultSet. getInt ( "max_salary" ) ;
System. out. println ( job_id+ "\t" + job_title+ "\t" + min_salary+ "\t" + max_salary) ;
}
rs. close ( ) ;
statement. close ( ) ;
connection. close ( ) ;
}
}
3.常见异常
java.lang.ClassNotFoundException
java.sql.SQLExceptio
与sql语句相关的错误 (约束错误、表名列名书写错误) 建议:在客户端工具中测试SQL语句之后再粘贴在代码中 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column
Duplicate entry ‘1’ for key ‘PRIMARY’
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘password’ in
原因:可能输入的值的类型不对,确定是否插入的元素时对应的值的类型正确
4.SQL注入问题
用户输入的数据中有SQL关键字或语法参与了SQL语句的编译,导致SQL语句编译后的条件含义出现不正常的现象,称为SQL注入。
5.PreparedStatement
作用: * 预编译SQL语句,效率高 * 安全,避免SQL注入 * 可以动态的填充数据,执行多个同构的SQL语句
PreparedStatement pstmt = conn. prepareStatement ( "select * from user where username=? and password=?" ) ;
pstmt. setString ( 1 , username) ;
pstmt. setString ( 2 , password) ;
6.对象关系映射(ORM)
在实际应用开发中,我们需要将零散的数据进行封装处理 通过实体类的属性与表字段一一对应,能够将一条记录封装到一个实体对象中
public class T_Jobs {
private String job_id;
private String job_title;
private int min_salary;
private int max_salary;
@Override
public String toString ( ) {
return "T_Jobs{" +
"job_id='" + job_id + '\'' +
", job_title='" + job_title + '\'' +
", min_salary=" + min_salary +
", max_salary=" + max_salary +
'}' ;
}
public String getJob_id ( ) {
return job_id;
}
public void setJob_id ( String job_id) {
this . job_id = job_id;
}
public String getJob_title ( ) {
return job_title;
}
public void setJob_title ( String job_title) {
this . job_title = job_title;
}
public int getMin_salary ( ) {
return min_salary;
}
public void setMin_salary ( int min_salary) {
this . min_salary = min_salary;
}
public int getMax_salary ( ) {
return max_salary;
}
public void setMax_salary ( int max_salary) {
this . max_salary = max_salary;
}
public T_Jobs ( ) {
}
public T_Jobs ( String job_id, String job_title, int min_salary, int max_salary) {
this . job_id = job_id;
this . job_title = job_title;
this . min_salary = min_salary;
this . max_salary = max_salary;
}
}
7.JDBC事务
JDBC中,可以通过Connection对象控制事务
setAutoCommit(false);//设置手动提交事务 commit();//提交事务 rollback();//回滚事务 JDBC中控制事务必须确保是同一个连接
public static void beginTransaction ( ) {
Connection connection = getConnection ( ) ;
try {
connection. setAutoCommit ( false ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
public static void commit ( ) {
Connection connection = getConnection ( ) ;
try {
connection. commit ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
close ( connection) ;
}
}
public static void rollback ( ) {
Connection connection = getConnection ( ) ;
try {
connection. rollback ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
close ( connection) ;
}
}
DBUtils. beginTransaction ( ) ;
try {
accountDao. outMoney ( username, money) ;
accountDao. inMoney ( outName, money) ;
DBUtils. commit ( ) ;
System. out. println ( "转账成功!" ) ;
} catch ( Exception e) {
System. err. println ( "转账失败!" ) ;
DBUtils. rollback ( ) ;
}
8.MVC三层架构
utils 存放工具类(DBUtils) entity 存放实体类(Person) dao 存放 DAO 接口(PersonDao)
impl 存放 DAO 接口实现类(PersonDaoImpl) service 存放 service 接口(PersonService)
impl 存放 service 接口实现类(PersonServiceImpl) view 存放程序启动类(main)
9.DaoUtils
public class DaoUtils {
public static int commonUpdate ( String sql, Object. . . args) {
Connection connection = DBUtils. getConnection ( ) ;
PreparedStatement prst = null;
try {
prst = connection. prepareStatement ( sql) ;
for ( int i = 0 ; i < args. length; i++ ) {
prst. setObject ( i + 1 , args[ i] ) ;
}
return prst. executeUpdate ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
DBUtils. close ( prst) ;
}
return 0 ;
}
public static < T> List< T> commonQuery ( String sql, Class< T> cls, Object. . . args) {
Connection connection = DBUtils. getConnection ( ) ;
List< T> list = new ArrayList < > ( ) ;
PreparedStatement prst = null;
try {
prst = connection. prepareStatement ( sql) ;
for ( int i = 0 ; i < args. length; i++ ) {
prst. setObject ( i + 1 , args[ i] ) ;
}
ResultSet rs = prst. executeQuery ( ) ;
Field[ ] fields = cls. getDeclaredFields ( ) ;
while ( rs. next ( ) ) {
try {
T t = cls. newInstance ( ) ;
for ( int i = 0 ; i < fields. length; i++ ) {
String filedName = fields[ i] . getName ( ) ;
Object value;
try {
value = rs. getObject ( filedName) ;
} catch ( SQLException e) {
String colName = DBUtils. getProperties ( ) . getProperty ( filedName) ;
value = rs. getObject ( colName) ;
}
fields[ i] . setAccessible ( true ) ;
fields[ i] . set ( t, value) ;
}
list. add ( t) ;
} catch ( InstantiationException e) {
e. printStackTrace ( ) ;
} catch ( IllegalAccessException e) {
e. printStackTrace ( ) ;
}
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
DBUtils. close ( prst, connection) ;
}
return list;
}
}
10.Druid连接池
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school
username=root
password=root
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000
public class DBUtils {
private static DataSource dataSource;
private static Properties properties;
private static ThreadLocal< Connection> threadLocal = new ThreadLocal < > ( ) ;
static {
properties = new Properties ( ) ;
try {
properties. load ( DBUtils. class . getClassLoader ( ) . getResourceAsStream ( "./db.properties" ) ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
try {
dataSource = DruidDataSourceFactory. createDataSource ( properties) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public static Connection getConnection ( ) {
Connection connection = threadLocal. get ( ) ;
try {
if ( connection == null) {
connection = dataSource. getConnection ( ) ;
threadLocal. set ( connection) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
return connection;
}
public static void close ( AutoCloseable. . . args) {
for ( AutoCloseable arg : args) {
if ( arg != null) {
try {
if ( arg instanceof Connection ) {
threadLocal. remove ( ) ;
}
arg. close ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
}
}