赞
踩
步骤:
1、注册驱动
2、创建连接
3、创建 Statement对象
4、编写sql语句 并且发送sql语句获得结果集
5、解析结果集
6、释放资源
注意事项 都在写下面代码里了
import com.mysql.cj.jdbc.Driver; import java.sql.*; import java.util.Properties; public class day1 { public static void main(String[] args) throws Exception { new test(); new test(); //注册驱动 不推荐 会注册两次 new Driver中有静态代码块 //DriverManager.registerDriver(new Driver()); //new Driver();//不推荐 不能显示出 是什么驱动 如果是8+ 则是com.mysql.cj.jdbc 如果是5+ 则是com.mysql.jdbc Class.forName("com.mysql.cj.jdbc.Driver"); //推荐 通过反射获得类加载 //建立连接 3种方式 ① // Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); // ② Properties properties=new Properties(); properties.put("user","ckytest"); properties.put("password","123456"); // Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test",properties); //③ Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?user=ckytest&password=123456"); //创建 mql Statement statement = ckytest.createStatement(); //mql 并发送 获取结果集 String mysql="select * from u_ser"; // statement.executeUpdate(); 非DML ResultSet resultSet = statement.executeQuery(mysql); while(resultSet.next()){ int anInt = resultSet.getInt(1); // int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println(anInt+"---"+name); } } }
步骤:
1、注册驱动
2、创建连接
3、编写sql语句
4、创建preparedStatement 对象并且传入sql语句
5、占位符赋值
从左到右 索引从1开始
6、发送sql语句获得结果集
7、解析结果集
8、释放资源
import com.mysql.cj.jdbc.Driver; import org.junit.Test; import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class test { @Test public void testinsert() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); String mysql="insert into u_ser(id,name) values(?,?);"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql); preparedStatement.setObject(1,3); preparedStatement.setObject(2,"yue"); int i = preparedStatement.executeUpdate(); if (i>0) System.out.println("成功"); preparedStatement.close(); ckytest.close(); } @Test public void testupdate() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); String mysql="update u_ser set name=? where id=?;"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql); preparedStatement.setObject(1,"cui"); preparedStatement.setObject(2,3); int i = preparedStatement.executeUpdate(); if (i>0) System.out.println("成功"); preparedStatement.close(); ckytest.close(); } @Test public void testdelete() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); String mysql="delete from u_ser where id=?;"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql); //preparedStatement.setObject(1,"cui"); preparedStatement.setObject(1,3); int i = preparedStatement.executeUpdate(); if (i>0) System.out.println("成功"); preparedStatement.close(); ckytest.close(); } //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value @Test public void testquery() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); String mysql="select * from u_ser;"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql); ResultSet resultSet = preparedStatement.executeQuery(); //得到表信息 ResultSetMetaData metaData = resultSet.getMetaData(); //得到列数量 int columnCount = metaData.getColumnCount(); List<Map> list=new ArrayList<>(); while(resultSet.next()) { Map map = new HashMap(); for (int i = 1; i <= columnCount; i++) { //获得结果 Object object = resultSet.getObject(i); //获得列名 String columnLabel = metaData.getColumnLabel(i); map.put(columnLabel, object); } list.add(map); } System.out.println(list); resultSet.close(); preparedStatement.close(); ckytest.close(); } }
String columnLabel = metaData.getColumnLabel(i);
getColumnLabel 有别名可以获得别名而getColumnName 不能获取别名。
getColumnCount 获取列的数量
getMetaData 获取列的信息
/** * * 得到自增长的主键 * 在创建prepareStatement,告知它拿回自增长的主键 * getGeneratedKeys 得到一个自增长主键的结果 首先通过next 移动光标 * 之后通过getxx 获取结果,插入一行 肯定只获取一个结果 所以是一行一列 索引为1 即使回显的主键 */ @Test public void testinsertkey() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456"); String mysql="insert into u_ser(name) values(?);"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS); preparedStatement.setObject(1,"yue1"); int i = preparedStatement.executeUpdate(); if (i>0) System.out.println("成功"); ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); generatedKeys.next(); Object id = generatedKeys.getObject(1); System.out.println("回显主键:"+id); preparedStatement.close(); ckytest.close(); }
在url中添上rewriteBatchedStatements=true,允许批量操作。
sql语句不要加分号
preparedStatement.addBatch();
preparedStatement.executeBatch();
@Test public void testinsert1() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456"); String mysql="insert into u_ser(name) values(?)"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { preparedStatement.setObject(1,"yue1"+i); preparedStatement.executeUpdate(); } long end = System.currentTimeMillis(); System.out.println("时间为:"+(end-start)/1000+"s"); //14s preparedStatement.close(); ckytest.close(); } @Test public void testabatchinsert() throws Exception{ Class.forName("com.mysql.cj.jdbc.Driver"); Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456"); String mysql="insert into u_ser(name) values(?)"; PreparedStatement preparedStatement = ckytest.prepareStatement(mysql); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { preparedStatement.setObject(1,"yue"+i); preparedStatement.addBatch(); } preparedStatement.executeBatch(); long end = System.currentTimeMillis(); System.out.println("时间为:"+(end-start)+"s");//0.77s preparedStatement.close(); ckytest.close(); }
原子性 一致性 隔离性 持久性
事务的发生 必须是在同一个连接中。
对于事务,我们应该在业务层进行开启和关闭。mysql是自动提交业务,我们可以手动开启或者关闭。
比如转账业务,我们可以在业务层获取一个连接,之后将该连接传入加钱和转钱方法,这样可以确保是一个连接。
事务,我们一般使用try,catch,如果成功就提交,捕捉到错误就回滚。
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import com.alibaba.druid.pool.DruidPooledConnection; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.util.Properties; public class DruidTest { public void druid1() throws Exception{ //创建连接池对象 DruidDataSource druidDataSource=new DruidDataSource(); //一些必要和不必要的选项 url,name,pwd,driver都是必须的 连接池数量这些不是必须的 druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test"); druidDataSource.setPassword("123456"); druidDataSource.setUsername("ckytest"); druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); druidDataSource.setInitialSize(5); druidDataSource.setMaxActive(10); //获得一个连接。 DruidPooledConnection connection = druidDataSource.getConnection(); //回收 connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。 } public void druid2() throws Exception{ //读取配置文件 Properties properties=new Properties(); //只要在src下 就可以使用类加载器 InputStream resourceAsStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties"); properties.load(resourceAsStream);//加载到properties中 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); //获得一个连接。 Connection connection = dataSource.getConnection(); //回收 connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。 } }
Url=jdbc:mysql://127.0.0.1:3306/test
Password=123456
Username=ckytest
DriverClassName=com.mysql.cj.jdbc.Driver
每次都去初始化连接池太麻烦了,我们封装一个工具类,对外提供一个获取连接和回收连接的方法。
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /* * 工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法 * 创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次 */ public class DruidUtils { //连接池 private static DataSource dataSource=null; static { Properties properties=new Properties(); InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } try { dataSource = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public Connection getConnection() throws SQLException { return dataSource.getConnection(); } public void closeConnection(Connection connection){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }
我们的工具类V1,只是单例模式了连接池,但是每次获取连接都是新的连接。
如果我们在Serve层获得一个连接,这个连接还需要传给Dao层来获取,能不能让同一个线程,Serve层和Dao层获取的都是同一个连接,而不用使用参数传递呢?可以使用线程局部变量。只要一个线程里边的属性就是通用的。
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /* * 工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法 * 创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次 */ public class DruidUtils { //连接池 private static DataSource dataSource=null; private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>(); static { Properties properties=new Properties(); InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } try { dataSource = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public Connection getConnection() throws SQLException { Connection connection=threadLocal.get(); if (connection==null){ connection = dataSource.getConnection(); threadLocal.set(connection); } return connection; } public void closeConnection() throws Exception{ Connection connection = threadLocal.get(); if (connection!=null){ threadLocal.remove(); connection.setAutoCommit(true); connection.close(); } } }
对于Dao层的封装,写一个基础BaseDao,对语句进行封装,可以分为DQL和非DQl两种。
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class A { public static int executUpdate(String sql,Object ... args) throws Exception{ Connection connection = DruidUtils.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 0; i <args.length ; i++) { preparedStatement.setObject(i+1,args[i]); } int i = preparedStatement.executeUpdate(); if (connection.getAutoCommit()){ //没有开启事务 DruidUtils.closeConnection(); } return i; } public static <T> List<T> executQuery(Class<T> tClass,String sql, Object ... args) throws Exception{ Connection connection = DruidUtils.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sql); if(args!=null&&args.length>0) { for (int i = 0; i <args.length ; i++) { preparedStatement.setObject(i+1,args[i]); } } ResultSet resultSet = preparedStatement.executeQuery(); //得到表信息 ResultSetMetaData metaData = resultSet.getMetaData(); //得到列数量 int columnCount = metaData.getColumnCount(); List<T> list=new ArrayList<>(); while(resultSet.next()) { Constructor<T> constructor = tClass.getConstructor(); T t = constructor.newInstance(); for (int i = 1; i <= columnCount; i++) { //获得结果 Object object = resultSet.getObject(i); //获得列名 String columnLabel = metaData.getColumnLabel(i); Field declaredField = tClass.getDeclaredField(columnLabel); declaredField.set(t,object); } list.add(t); } if (connection.getAutoCommit()){ //没有开启事务 DruidUtils.closeConnection(); } return list; } }
数据库每个表都对应java中的一个实体类,查询时我们返回的是一个装有实体类的集合。
封装过工具类之后的增删改查 简化了很多。
import com.mysql.cj.jdbc.Driver; import org.junit.Test; import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class test { @Test public void testinsert() throws Exception{ String mysql="insert into u_ser(id,name) values(?,?);"; int a = A.executUpdate(mysql, 50001, "a"); System.out.println(a); } @Test public void testupdate() throws Exception{ String mysql="update u_ser set name=? where id=?;"; int a = A.executUpdate(mysql, "cui", 1); System.out.println(a); } @Test public void testdelete() throws Exception{ String mysql="delete from u_ser where id=?;"; int a = A.executUpdate(mysql, 1); System.out.println(a); } //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value @Test public void testquery() throws Exception{ String mysql="select * from u_ser;"; List<User> users = A.executQuery(User.class, mysql); System.out.println(users); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。