Java+MySQL综合运用笔记
一.Java连接使用mysql的5个思路过程
首先导入JDBC驱动jar包放到lib文件夹里面。
1.加载驱动方法
①注册驱动:DriverManager.registerDriver(new com.mysql.jdbc.Driver());
②反射静态代码段驱动:Class.forName(“com.mysql.jdbc.Driver”);
2.建立连接
①数据库路径:String url=“jdbc:mysql://localhost:3306/mydb1”;其中3306是数据库端口号,mysql1是数据库名。
②用户名:String user=“root”;
③用户密码:String pwd=“hry110”;
Connection conn = DriverManager.getConnection(url,user,pwd);
技巧1:可以把驱动的数据库,数据库路径,用户名和密码放在source文件中的db.properties文本中
driverName = "com.mysql.jdbc.Driver";
url = "jdbc:mysql://localhost:3306/mydb1";
user = "root";
password = "hry110";
技巧:2:1和2可以封装成一个返回值类型为Connection的getConnection()方法专门用于连接。
优化方法:
①在source文件夹下db.properties文本中配置数据库信息
driverName = "com.mysql.jdbc.Driver";
databasePath = "jdbc:mysql://localhost:3306/mydb1";
user = "root";
password = "hry110";
②封装类
/**
* 工具类:负责连接数据库、获取Statement对象、资源释放
* @author luds
*/
public class JDBCUtil {
private JDBCUtil() {}
private static Properties pro = new Properties();
/**
* 驱动的注册只需要注册一次即可,所以可以将注册驱动代码写到静态代码段中。
*/
static {
// pro.load(new BufferedReader(new FileReader("db.properties")));
// 使用ClassLoader来加载一个Properties里面的数据
// 1. 创建ClassLoader对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// 2. 获取用于操作某个文件的字节流对象
InputStream in = loader.getResourceAsStream("db.properties");
// 3. 加载数据
try {
pro.load(in);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Class.forName(pro.getProperty("driverName"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 注册驱动、建立与数据库的连接
* @return
*/
public static Connection getConnection() {
try {
// 2. 获取连接
Connection conn = DriverManager.getConnection(pro.getProperty("databasePath"), pro.getProperty("user"), pro.getProperty("password"));
return conn;
} catch (Exception e) {
e.printStackTrace();
}
throw new RuntimeException("数据库连接失败");
}
/**
* 资源释放
* @param conn
* @param st
* @param set
*/
public static void release(Connection conn, Statement st, ResultSet set) {
if (set != null) {
try {
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3.Statement执行语句
⑴Statement st=conn.createStatement();
4.执行SQL语句
PreparedStatement 预编译:通过PreparedStatement 预编译类语句实现增删改查
Batch批处理:通过Batch实现增删改查。 batch进行创建表待续
❶增:
①基本版增:
⑴sql插入语句:String sql = “insert into t_teacher values (6, ‘张无忌’,‘男‘)”;
String sql = String.format(“insert into t_teacher values(%d, %s, %s)”, st.getAge(),st.getName(), , st.getGender());用于自定义数据模型类。
⑵执行插入:int rows=st.executeUpdate(sql);//返回值为int
⑶输出结果:sout(rows);
②PreparedStatement增
⑴sql插入语句:String sql = “insert into t_teacher values (?,?,?)”;其中?是占位符。
⑵执行插入:PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 10);
ps.setString(2, "张无忌");
ps.setString(3, "男");
⑶输出结果:int rows = ps.executeUpdate(); sout(rows);
③Batch增
⑴关闭自动提交:conn.setAutoCommit(false);
⑵批量添加:
st.addBatch("insert into t_teacher values (3, '郭靖', '男')");
st.addBatch("insert into t_teacher values (4, '黄蓉', '女')");
st.addBatch("insert into t_teacher values (5, '郭襄', '女')");
st.addBatch("insert into t_teacher values (6, '小龙女', '女')");
st.addBatch("insert into t_teacher values (7, '韦小宝', '男')");
⑶批量执行:int[] rows = st.executeBatch();
⑷批量输出for(int r : rows) {System.out.println®;}
⑸任务提交:conn.commit();
❷删
①基本版删除
⑴sql删除语句:String sql = “delete from t_teacher where sid=1;”;
String sql = "delete from t_teacher where sid =+id+; " ;用于自定义数据模型类。
⑵执行删除:int rows=st.executeUpdate(sql);//返回值为int
⑶输出结果:sout(rows);
②
③Batch删除:
⑴关闭自动提交:conn.setAutoCommit(false);
⑵批量删除:
st.addBatch("delete from t_teacher where tname = '小龙女'");
⑶批量执行:int[] rows = st.executeBatch();
⑷批量输出for(int r : rows) {System.out.println®;}
⑸任务提交:conn.commit();
❸改
①基本版改:
①基本版删除
⑴sql修改语句: String sql = String.format(“update t_student set sname = %s, sage = %d, sgender = %s, score_java = %d, score_mysql = %d, score_hadoop = %d, score_spark = %d, groupid = %d, cid = %d where sid = %s”, st.getName(), st.getAge(), st.getGender(), st.getScoreJava(), st.getScoreMysql(), st.getScoreHadoop(), st.getScoreSpark(), st.getGroupID(), st.getClassID(), id);用于自定义数据模型类。
⑵执行修改:int rows=st.executeUpdate(sql);//返回值为int
⑶输出结果:sout(rows);
②
③Batch修改:
⑴关闭自动提交:conn.setAutoCommit(false);
⑵批量修改:
st.addBatch("update t_teacher set tname = '杨康' where id = 7");
⑶批量执行:int[] rows = st.executeBatch();
⑷批量输出for(int r : rows) {System.out.println®;}
⑸任务提交:conn.commit();
❹查
①基本版查:
⑴String sql=“select * from t_student”;
⑵ResultSet set=st.executeQuery(sql);
⑶循环一行一行获取数据:
while (set.next()) {
int id = set.getInt(1);
String name = set.getString("sname");
String gender = set.getString(3);
int age = set.getInt("sage");
int score = set.getInt("score");
sout(String.format("|%d|%s|%s|%d|%d|", id, name, gender, age, score));
}
②
③Batch查:
⑴关闭自动提交:conn.setAutoCommit(false);
⑵批量修改:
st.addBatch("select * from t_teacher");
⑶批量执行:int[] rows = st.executeBatch();
⑷批量输出for(int r : rows) {System.out.println®;}
⑸任务提交:conn.commit();
5.释放资源
conn.close() st.close() set.close()
技巧:可以用方法封装好Connection,Statement和ResultSet ,前两个用于增删改查,后一个仅仅用于查。
二.连接池
对自定义的JDBCUti类进行再次封装。
注意啊。这里为什么不配置数据库文件,是因为线程池实现是JDBCUtil自定义的类,在db.properties已经配置好了
1.作用:实现一个Connection对象的复用,减少性能损耗和时间损耗,其实就是对JDbc中的JDBCUtil类再进行封装数据库连接和数据库资源释放。
2.思路:设计pool类实现连接的获取和连接的归还的两个方法。
①属性:集合,用来存放Connection对象
(1)连接池容量:private static int capcity = 10;
(2)复用池:private static LinkedList list = new LinkedList<>();作用是获取连接和归还连接。
(3)使用静态代码段默认填充复用池连接
static {
// 默认填充复用池中的连接,手动定义一个连接池的容量
for (int i = 0; i < capcity; i++) {
// 存放Connection对象
Connection conn = JDBCUtil.getConnection();
list.add(conn);
}
}
②方法:获取连接、归还连接
(1)获取连接
public static Connection getConnection() {
// 1. 判断复用池中有没有Connection对象
if (list.size() > 0) {
// 2. 说明此时连接池中是有Connection对象
// 3. 从池子中取出一个对象返回即可
return list.removeFirst();
}
// 如果此时池子中没有连接对象
// 理论上需要做一个等待时间:在等待时间内,如果有Connection归还,可以直接获取。如果等待超时,则直接创建一个新的Connection对象返回
// 不去模拟等待时长,直接返回一个新的
return JDBCUtil.getConnection();
}
(2)归还连接
public static void close(Connection conn) {
// 1. 判断池子的容量是不是达到了最大值
if (list.size() >= capcity) {
// 说明池子已经存满了,这个conn直接释放即可,不用添加到池子中
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
else {
// 说明复用池还不满,此时将归还的conn添加到集合中即可
list.add(conn);
}
}
三.DBCP
1.作用:实现一个Connection对象的复用,减少性能损耗和时间损耗,其实就是对JDbc中的JDBCUtil类再进行封装数据库连接和数据库资源释放,与连接池不同的是,连接池是用集合存Connection对象,而DBCP是用DataSource 来存取Connection对象。
2.实现思路:设计类DBCPUtil 实现连接的获取和连接的归还的两个方法,必须先导入jdbc,dbcp和pool三个jar包。
(1)在source文件夹配置数据库dbcp.properties文件:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1
username=root
password=hry110
maxActive=20
(2)DataSource接口属性:private static DataSource ds:存连接对象容量。
(3)使用静态代码段默认填充连接工厂
static {
Properties p = new Properties();
try {
// 1. 读取properties里面的资源 p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("dbcp.properties"));//特别注意需要配置数据库文本信息,这里我配置在后面。
// 2. 获取连接池对象
// BasicDataSourceFactory:用来获取一个DataSource对象的工厂
ds = BasicDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
}
4.方法:获取连接和释放资源 注意哦:可以有五个释放资源方法,一到三形参五个
(1)获取连接方法
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
throw new RuntimeException("获取连接失败");
}
(2)释放连接方法三个
1.Connection连接的释放。
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2.释放Statement 资源
public static void close(Statement st) {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3.释放ResultSet 资源
public static void close(ResultSet set) {
if (set != null) {
try {
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
注意啊Apache:BasicDataSource 实例化对象ds,需要导入jdbc,DBCP和pool的jar包,需对Connection,Statement,ResultSet资源释放。
①实例化BasicDataSource ds = new BasicDataSource();
②设置驱动:ds.setDriverClassName(“com.mysql.jdbc.Driver”);
③设置数据库的路径:ds.setUrl(“jdbc:mysql://localhost:3306/mydb1”);
④设置用户名:ds.setUsername(“root”);
⑤设置密码:ds.setPassword(“hry110”);
⑥设置最大连接数:ds.setMaxActive(20);
⑦获取连接:ds.getConnection();
四.C3P0
比较特殊不需要手动配置驱动,所有数据库配置信息都放在c3p0-config,xml中。
注意:是一个xml文件:c3p0-config.xml ,而且这个文件需要放到source下面
1.作用:对数据库连接对象Connection和资源释放进行封装。
2.使用思路:设计类C3P0Utils实现连接的获取和连接的释放。
①首先导入jar包:jdbc.jar和c3p0.jar。
②在source文件夹配置数据库c3p0-config,xml文件:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
<property name="user">root</property>
<property name="password">hry110</property>
<property name="initialPoolSize">10</property>
</default-config>
</c3p0-config>
注意数据库的配置还可以使用 ComboPooledDataSource cpds=new ComboPooledDataSource();
cpsd.setDriveClass(“com.mysql.jdbc.Driver”) ; 加载驱动。
cpsd.setJdbcUrl(”jdbc:mysql://localhost:3306/mydb1“) ; 获取数据库路径
cpsd.setUser(“root”); 设置用户名
cpsd.setPassword(“hry110”); 设置用户密码
cpsd.setInitialPoolSize(10); 设置初始化的连接数量====》接下来就是获取连接,statement语句了。
②实例化对象:ComboPooledDataSource ds = new ComboPooledDataSource();
②实例化对象:ComboPooledDataSource ds = new ComboPooledDataSource();
③获取连接:Connection conn = ds.getConnection();
④statement语句:Statement st = conn.createStatement();
⑤接下来就是sql语句,执行statement增删改查语句,最后资源释放。
五.Druid
1.作用:对connection对象连接和释放。
2.使用思路: 实现连接的获取和资源的释放。
①导jar包:jdbc.jar和druid.jar包。
②实例化对象:DruidDataSource ds = new DruidDataSource();
③设置驱动:ds.setDriverClassName(“com.mysql.jdbc.Driver”);
④设置数据库路径:ds.setUrl(“jdbc:mysql://localhost:3306/mydb1”);
⑤设置用户名:ds.setUsername(“root”);
⑥设置密码:ds.setPassword(“hry110”);
⑦获取连接:ds.setPassword(“123456”);
六.DBUtils
比较特殊不需要手动配置驱动,所有数据库配置信息都放在c3p0-config,xml中。
1.作用:对connection对象连接和释放。
2.使用思路: 实现连接的获取和资源的释放。
①导入jar包:jdbc.jar,dbutils.jar和c3p0.jar包。
②在source文件夹配置数据库c3p0-config.xml文件:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">10</property>
</default-config>
</c3p0-config>
③C3P0获取数据库资源:
class C3P0Utils {
private static ComboPooledDataSource ds = new ComboPooledDataSource();
/**
* 获取一个DataSource连接池
* @return
*/
public static DataSource getDataSource() {
return ds;
}
}
④实例化QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());
⑤执行增删改:
(1)增:
int rows = runner.update("insert into t_test values(1001, 'Uncle Wang')");
System.out.println(rows);
(2)删:
(3)改:
rows = runner.update("insert into t_test values(?,?)", 1002, "Uncle Li");
System.out.println(rows);
⑥执行查询:
(1)建立一个User类实现对数据库中数据进行getter和setter,重写toSTring()和有参构造方法。
(2)查一行:BeanHandler,ArrayHandler,MapHandler
User user = runner.query("select * from t_users", new BeanHandler<>(User.class));
System.out.println(user);
(3)查多行:BeanListHandler,ArrayListHandler,MapListHandler
List<User> result = runner.query("select * from t_users", new BeanListHandler<>(User.class));
for (User u : result) {
System.out.println(u);}