Java 技术连接数据库的几种方式以及数据库连接池的创建方式:
1、
`package com.com.taopan;
import java.sql.*;
public class DBUtil {
private static Connection conn=null;
private final static String URL="jdbc:mysql://localhost:3306/stu_crm";
private final static String USER="root";
private final static String PASSWORD="123";
public static Connection getConn(){
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("加载驱动成功");
conn= DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println("连接成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static void close(Connection conn, ResultSet rs, PreparedStatement ps){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
直接操作,直接连接法,每需要一个链接就创建一个connection。这种方式适用于大部分初学者,但是这种连接对于数据而言就会很麻烦,比如查询表的全部信息:
ps=conn.prepareStatement(sql_query);
rs=ps.executeQuery();
while (rs.next()){
Lesson lesson=new Lesson();
lesson.setId(rs.getInt("ID"));
lesson.setLessonName(rs.getString("lessonName"));
lesson.setLessonCost(rs.getDouble("lessonCost"));
lesson.setTotalTime(rs.getInt("totalTime"));
lesson.setRemark(rs.getString("remark"));
lessons.add(lesson);
他需要将数据一个一个放入实体类当中比较繁琐。
2、通过datasource的连接:
public class DataSourceUtil {
private static DataSource ds;
static {
InputStream in=DataSourceUtil.class.getClassLoader().getResourceAsStream("dbcp.properties");
Properties properties=new Properties();
try {
properties.load(in);
ds=new BasicDataSourceFactory().createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return ds;
}
public static Connection getConn(){
Connection connection=null;
try {
connection= ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
}
每次需要一个连接就可以直接通过getCon()方法获取,但是在数据上会有明显的优势。
QueryRunner qr=new QueryRunner(DataSourceUtil.getDataSource());
String sql_query="select * from crm_lessontype";
List<Lesson>lessons=null;
try {
lessons=qr.query(sql_query,new BeanListHandler<Lesson>(Lesson.class));
} catch (SQLException e) {
e.printStackTrace();
}
return lessons;
它不需要将数据一个一个的存放在实体类当中,只是通过底层实现了这个。但是有个条件就是,实体类必须和数据表的属性名字一样。
对于查询,还有很多方式:查询一个Bean:new BeanHandler
查询一个字段:ColumnListHandler
修改、删除、增加都是用update,如:
QueryRunner qr=new QueryRunner(DataSourceUtil.getDataSource());
String sql_update="update crm_lessontype set totalTime="+lesson.getTotalTime()+"where ID="+lesson.getId();
try {
qr.update(sql_update);
} catch (SQLException e) {
e.printStackTrace();
}
连接池—
在Java中,任何池的概念都是通过集合的方式去实现。
1、那个集合实现?
List集合中,arrayList方便查找,不方便增删
LinkedList方便增删不方便查。
而数据连接不需要查,所以选择下面的。
有以下几种方式实现:
static{
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("加载驱动成功");
for (int i=0;i<=3;i++){
conn= DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(pool);
pool.add(conn);
}
System.out.println("连接"+pool.size());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Connection getConn(){
Connection connection=pool.remove(0);
try {
Thread.sleep(100);
System.out.println(pool.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return connection;
}
public static void back(Connection connection){
pool.add(connection);
System.out.println(pool.size());
}
通过pool.remove方法删除在pool集合中的一个Connection,然后返回给需要的,这样就实现了要用就取的方式。还的话就直接将这个connection添加在集合中就可以。
2、
private static LinkedList<Connection> pool=new LinkedList<Connection>();
static {
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/stu_crm";
for (int i = 0; i <= 3; i++) {
Connection connection= DriverManager.getConnection(url,"root","123");
Object p= Proxy.newProxyInstance(DBUtilPool.class.getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("close")){
synchronized (pool) {
pool.add((Connection) proxy);
pool.notify();//通知其他线程pool中添加了东西
}
return null;
}
Object returnvalue=method.invoke(connection,args);
return returnvalue;
}
});
pool.add((Connection)p);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Connection getConn(){
if(pool.size()==0){
try {
pool.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return getConn();
}
return pool.removeFirst();
}
通过动态代理的方式,首先,在加载时Static{}的东西便会加载到内存中,在需要时,通过同步的方式判断pool中的长度,以便看出pool中是否还有链接,若没有则等待。
若有,则取。还的方式是动态代理,就可以看出归还。