步骤
- 为项目导入mysql-jdbc的jar包
- 初始化驱动 通过类加载器将驱动在内存中进行注册
- 建立与数据库的连接
- 创建Statement
- 执行SQL语句
- 关闭连接(finally关键字) 或者使用try-with-resource的方式自动关闭连接 Connection和Statement都实现了AutoCloseable接口 所以可以使用
public class DBUtil {
static String ip = "127.0.0.1";
static int port = 3306;
static String database = "tmall";
static String encoding = "UTF-8";
static String loginName = "root";
static String password = "1234";
static{
try{
Class.forName("com.mysql.cj.jdbc.Driver");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
String url = String.format("jdbc:mysql://%s:%d/%s?characterEncoding=%s&serverTimezone=Asia/Shanghai", ip, port, database, encoding);
return DriverManager.getConnection(url, loginName, password);
}
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
}
PreparedStatement
可以设置参数,指定相应的值,而不是Statement那样使用字符串拼接
可读性好,不易犯错,维护性好,有预编译机制,性能比Statement更快。因为不是字符串拼接,所以可以防止sql注入
注意这里属性的序号是从1开始的 是java中唯二基1的 另一个是查询语句中的ResultSet
String sql = "insert into hero values(null,?,?,?)";
try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root", "admin");
// 根据sql语句创建PreparedStatement
PreparedStatement ps = c.prepareStatement(sql);
) {
// 设置参数
ps.setString(1, "提莫");
ps.setFloat(2, 313.0f);
ps.setInt(3, 50);
// 执行
ps.execute();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
execute与executeUpdate的区别
相同点:都可以执行增加,删除,修改
不同1:
execute可以执行查询语句
然后通过getResultSet,把结果集取出来
executeUpdate不能执行查询语句
不同2:
execute返回boolean类型,true表示执行的是查询语句,false表示执行的是insert,delete,update等等
executeUpdate返回的是int,表示有多少条数据受到了影响
try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root", "admin");
Statement s = c.createStatement();) {
// 不同1:execute可以执行查询语句
// 然后通过getResultSet,把结果集取出来
String sqlSelect = "select * from hero";
s.execute(sqlSelect);
ResultSet rs = s.getResultSet();
while (rs.next()) {
System.out.println(rs.getInt("id"));
}
// executeUpdate不能执行查询语句
// s.executeUpdate(sqlSelect);
// 不同2:
// execute返回boolean类型,true表示执行的是查询语句,false表示执行的是insert,delete,update等等
boolean isSelect = s.execute(sqlSelect);
System.out.println(isSelect);
// executeUpdate返回的是int,表示有多少条数据受到了影响
String sqlUpdate = "update Hero set hp = 300 where id < 100";
int number = s.executeUpdate(sqlUpdate);
System.out.println(number);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
在Statement通过execute或者executeUpdate执行完插入语句后,MySQL会为新插入的数据分配一个自增长id 通过getGeneratedKeys()方法拿到这个id
String sql = "insert into hero values(null,?,?,?)";
try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root", "admin");
PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
) {
ps.setString(1, "盖伦");
ps.setFloat(2, 616);
ps.setInt(3, 100);
// 执行插入语句
ps.execute();
// 在执行完插入语句后,MySQL会为新插入的数据分配一个自增长id
// JDBC通过getGeneratedKeys获取该id
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
System.out.println(id);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
事务
表的类型是INNODB mysql服务器需要开INNODB
在事务中的多个操作,要么都成功,要么都失败
通过 c.setAutoCommit(false);关闭自动提交
使用 c.commit();进行手动提交
c.setAutoCommit(false);
// 加血的SQL
String sql1 = "update hero set hp = hp +1 where id = 22";
s.execute(sql1);
// 减血的SQL
String sql2 = "update hero set hp = hp -1 where id = 22";
s.execute(sql2);
// 手动提交
c.commit();