进阶篇存在的问题
- 进阶篇对代码进行了一定的封装,还是不够。
1.可以看看Intellij IDEA对我们代码的提示
可以看出,这些代码依旧是重复,可以进行提取
如获取连接 和关闭连接等代码每次增删改查的需要些一遍。
2.使用 Statement来产生sql语句对象,需要对sql语句进行字符串联。代码也会繁杂。
String sql="DELETE from `user` where userId="+userId;
如何解决这些问题
- 使用PreparedStatement 替代Statement
基于以下的原因:
一.代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次。
二.PreparedStatement尽最大可能提高性能。
三.最重要的一点是极大地提高了安全性.对传入的内容进行甄别。
更多优点可以百度一下。 - 以添加为例优化我们的代码
//保存一条数据
public boolean saveUser(User user) {
boolean flag = false;
//获取连接
Connection conn = null;
//产生执行sql语句的对象
PreparedStatement ps =null;
//加载驱动
try {
Class.forName(jdbDriver);
conn = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPassword);
//插入一条记录
String sql="INSERT into user (username,password) VALUES (?,?)";
ps=conn.prepareStatement(sql);
//参数赋值
ps.setString(1,user.getUsername());
ps.setString(2,user.getPassword());
//执行sql语句
int rows = ps.executeUpdate();
if (rows > 0) {
flag=true;
System.out.println("插入数据成功!");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(st !=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
return flag;
}
使用PreparedStatement如何进行对集合查询
- 需要一个ResultSet ,通过这个指针rs.next()来一条条查询表中数据
//根据UserId查询数据
public User selectByUserId(int userId){
User user =null;
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
Class.forName(jdbDriver);
conn = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPassword);
String sql ="select * from user where userId =?";
ps=conn.prepareStatement(sql);
ps.setInt(1,userId);
//执行一个sql语句返回结果集
rs=ps.executeQuery();
if (rs.next()){
user=new User();
user.setUserId(rs.getInt("userId"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setSex(rs.getInt("sex"));
user.setFlag(rs.getInt("flag"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源,先产生的后关闭
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(st !=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
} }
return user;
}
重复使用的代码封装成工具类的方法
这里可以把创建连接和关闭连接等进行提取
public class DBConnectionUtil {
private static String jdbDriver = "com.mysql.jdbc.Driver";
private static String jdbcURL = "jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf-8";
private static String jdbcUser = "root";
private static String jdbcPassword = "123456";
public static Connection getConnection() {
//获取连接
Connection conn = null;
//产生执行sql语句的对象
Statement st = null;
//加载驱动
try {
Class.forName(jdbDriver);
conn = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPassword);
System.out.println(conn);
st = conn.createStatement();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static void closeAll(ResultSet rs,Statement st, Connection conn){
//关闭资源,先产生的后关闭
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(st !=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
我们封装工具类之后,就要使用工具类的方法了,把以前重复的代码替换掉。
添加
//保存一条数据
public boolean saveUser(User user) {
boolean flag = false;
//获取连接
Connection conn = null;
//产生执行sql语句的对象
PreparedStatement ps =null;
//加载驱动
try {
conn = DBConnectionUtil.getConnection();
System.out.println(conn);
//插入一条记录
String sql="INSERT into user (username,password) VALUES (?,?)";
ps=conn.prepareStatement(sql);
//参数赋值
ps.setString(1,user.getUsername());
ps.setString(2,user.getPassword());
//执行sql语句
int rows = ps.executeUpdate();
if (rows > 0) {
flag=true;
System.out.println("插入数据成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源,先产生的后关闭
DBConnectionUtil.closeAll(null,ps,conn);
}
return flag;
}
查询
//根据UserId查询数据
public User selectByUserId(int userId){
User user =null;
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
conn=DBConnectionUtil.getConnection();
String sql ="select * from user where userId =?";
try {
ps=conn.prepareStatement(sql);
ps.setInt(1,userId);
//执行一个sql语句返回结果集
rs=ps.executeQuery();
if (rs.next()){
user=new User();
user.setUserId(rs.getInt("userId"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setSex(rs.getInt("sex"));
user.setFlag(rs.getInt("flag"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源,先产生的后关闭
DBConnectionUtil.closeAll(rs,ps, conn);
}
return user;
}
写个测试类试试效果
public class Test02 {
public static void main(String[] args) {
UserDao userDao =new UserDao();
User user=new User();
user.setUsername("xiaoka");
user.setPassword("123456");
boolean flag =userDao.saveUser(user);
System.out.println(flag?"插入成功!":"插入失败");
}
}
测试查询
User user=userDao.selectByUserId(6);
System.out.println(user);
- 数据库文件和实体类在阶段复习之jdbc连接数据库(一)——基础篇