1.JDBC环境搭建步骤:
第一步: 导包,即导入相应的mysql数据库驱动 mysql-connector-java-5.1.43.jar
第二步: 加载驱动
第三步: 获取连接
第四步: 创建一个Statement对象,用于承载SQL语句
第五步: 执行语句,处理运行结果
第六步: 释放资源
@Test
public void testJDBC() throws ClassNotFoundException, SQLException {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 建立连接:
//第一个参数是url: jdbc:mysql://IP:端口号/数据库名
//第二个参数是数据库用户名
//第三个参数是数据库密码
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "xxx", "xxx");
//sql用于存储增删改查语句
String sql = "select * from test";
// 创建一个statement对象,用于承载sql语句
Statement st = conn.createStatement();
// 执行sql语句,并处理结果
ResultSet rs = st.executeQuery(sql);// executeQuery():查询操作
// st.executeUpdate(sql);//executeUpdate:用于增删改
//遍历结果集ResultSet
while (rs.next()) {
//取出数据通过getInt()、getString()等方法
System.out.println(rs.getInt("id") + rs.getString("name"));
}
// 关闭资源:先打开的后关闭
rs.close();
st.close();
conn.close();
}
2.PreparedStatement与Statement的区别:
a.Statement用于执行静态的SQL语句,而且在执行的时候,必须使用事先准备好的SQL语句,会有SQL注入风险,不太安全
b.PreparedStatement是属于预编译的SQL语句对象,在执行的SQL语句中可以使用?传递参数,能够避免SQL主语风险
@Test
public void testPreparedStatement() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "xxx", "xxx");
String sql = "select * from test where id=?";// 用?动态传递参数
// prepareStatement():创建PreparedStatement对象
PreparedStatement pSt = conn.prepareStatement(sql);
// 设置?参数的值,
/*
* setInt()、setString()等
*/
pSt.setInt(1, 10);// 第一个参数为 指向第几个?号, 第二个参数为传入的值
ResultSet rs = pSt.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
}
rs.close();
pSt.close();
conn.close();
}
3.Batch多语句操作:
@Test
public void testBatch() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "xxx", "xxx");
Statement st = conn.createStatement();
st.addBatch("insert into test (id,name,money) values(21,'st多条测试1',99.12)");
st.addBatch("insert into test (id,name,money) values(22,'st多条测试2',99.22)");
st.addBatch("insert into test (id,name,money) values(23,'st多条测试3',99.32)");
st.addBatch("insert into test (id,name,money) values(24,'st多条测试4',99.42)");
st.executeBatch();
System.out.println("执行成功");
st.close();
conn.close();
}
4.事务机制
就JDBC默认情况下,是执行一条SQL语句就在数据库中保存一次数据,如果同时执行多条语句,其中有语句存在错误,那么这个时候就需要同时成功或同时失败,否则数据库的数据就会出错
就上述问题,如果开启了事务机制,在执行中发生问题,程序会回滚到没有操作之前,即数据库数据不会发生变化
Connection conn = null;
Statement st = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306:/test", "xxx`", "xxx");
// 取消自动提交
conn.setAutoCommit(false);
String sql_01 = "insert into test(id,name,age) values(1,'张三',10)";
String sql_02 = "insert into test(id,name,age) values(1,'张三',10)";
String sql_03 = "insert into test(id,name,age) values(1,张三,10)";// 该语句会发生错误,因为张三不是字符串类型
st = conn.createStatement();
st.addBatch(sql_01);
st.addBatch(sql_02);
st.addBatch(sql_03);
st.executeBatch();
// 事物提交
conn.commit();
} catch (Exception e) {
try {
// 事物回滚,第三条语句出错就会进入这里,执行事物回滚
conn.rollback();
e.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5.读取配置文件:(properties)
.properties文件规范:数据格式为:key=value形式, 一行只写一个k,v ,键值对写完后不加;(分号)
对配置文件进行读取:
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
// 创建一个Properties对象
Properties prop = new Properties();
// 将prop对象与配置文件相关联
/*
* getClassLoader : 获取类加载器 ; getResourceAsStream : 把资源转换为流
*/
InputStream ins = Properties.class.getClassLoader().getResourceAsStream("jdbc.properties");
prop.load(ins);
// 读取数据
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
/*
* JDBC连接...
*/
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
}
6.DBUtils框架: 简化传统JDBC代码量的强大工具
使用步骤:
a.导入jar包 commons-dbutils-1.6.jar
b.创建核心类 QueryRunner
c.测试
public class UserDaoImpl {
//创建核心类
private QueryRunner qr = new QueryRunner();
@Test
public void insertUser() throws Exception {
//JdbcUtil.getConn():自己封装的传统JDBC类,用于获取Connection对象
//qr.update():可用于增删改
int flag = qr.update(JdbcUtil.getConn(), "INSERT INTO users SET username=?,PASSWORD=?",new Object[]{ "老郭", "123" });
System.out.println("flag=" + flag);
}
//--------------------查询-----------------------
@Test
public void getUserById() throws Exception {
//qr.query(Connection,sql,ResultSetHandler):用于查询操作
/**
* ResultSetHandler:结果集处理器,告诉Dbutils框架最终返回的结果使用何种类型来封装
* 常见的结果集处理器7个:
* BeanHandler:处理JavaBean数据类型
*/
User user = qr.query(JdbcUtil.getConn(), "select * from users where id=1049",
new BeanHandler<User>(User.class));
System.out.println(user);
}
@Test
public void getUserById2() throws Exception {
//MapHandler():
Map<String, Object> userMap = qr.query(JdbcUtil.getConn(), "select * from users where id=1049",new MapHandler());
System.out.println(userMap);
}
@Test
public void getUserById3() throws Exception {
//MapListHandler():
List<Map<String, Object>> mapList = qr.query(JdbcUtil.getConn(), "select * from users", new MapListHandler());
for (Map<String, Object> map : mapList) {
System.out.println(map);
}
}
}
常见的ResultSetHandler处理集:
7.包命名规范:
dao.impl: 存放操作数据库的代码
entity/POJO/JavaBean/domain: 存放实体类
utils: 存放自己封装的工具类
resource源文件夹: 配置文件
...
8.数据流连接池 : druid、c3p0等
导入jar包
将下面语句写入jdbc.properties配置文件中
#配置mysql
#配置基本属性
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///数据库名
username=
password=
#配置初始化大小、最小、最大
initialSize=5
minIdle=1
maxActive=20
#配置获取一个数据库连接最多需要等待的时间
maxWait=60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis=60000
#配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis=30000