package march.part0320.dao.impl;
import march.part0320.dao.UserDao;
import march.part0320.entity.User;
import march.part0320.util.DateUtil;
import march.part0320.util.JdbcTemplate;
import march.part0320.util.JdbcUtil;
import java.sql.*;
public class UserDaoImpl implements UserDao {
@Override
public void add(User user) {
String sql = "insert into t_user(t_username,t_pwd,t_createtime) values (?,?,now())";
JdbcTemplate.executeUpdate(sql,user.getUserName(),user.getPwd());
}
@Override
//希望做成模板
public User query(String userName, String pwd) {
User user = null;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection = null;
connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
//也有可能select···from dept
//模板:大部分相同一些地方不相同
//SQL、参数、O/R Mapping的格式不一样
String sql = "select t_username,t_pwd,t_createtime from t_user where t_username = ? and t_pwd = ?";
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,userName);
preparedStatement.setString(2,pwd);
//参数可能不一样
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
//O/R Mapping的过程
user = new User(resultSet.getString("t_username"),resultSet.getString("t_pwd"), DateUtil.strToDate(resultSet.getString("t_createtime"),"yyyy-MM-dd HH:mm:ss"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(resultSet,preparedStatement,connection);
}
return user;
}
}
在JdbcTemplate中添加统一的查询方法
package march.part0320.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JdbcTemplate {
public static void executeUpdate(String sql,Object ... preparedStatements) {
Connection connection = null;
connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
setPreparedStatements(preparedStatement,preparedStatements);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement,connection);
}
}
private static void setPreparedStatements(PreparedStatement preparedStatement,Object ... preparedStatements) {
if (!(null == preparedStatement || preparedStatements.length == 0)) {//有参数
for (int i = 0 ; i < preparedStatements.length ; i++) {
try {
preparedStatement.setObject((i + 1),preparedStatements[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public static List
困惑:
没有办法处理映射的过程。
根本原因:
因为实体类与实体类之间的差异性很大,借鉴
java.sql包的设计方案:数据库差异很大,只能提供标准,让数据库厂家自行实现,
因此在这里,我们也把映射的过程设计成接口,让具体的实体类自行实现。
RowMapping接口 行映射器
package march.part0320.util;
import java.sql.ResultSet;
import java.sql.SQLException;
@FunctionalInterface//当一个接口中只有一个抽象方法时,就是一个函数式接口
//可以使用lambda表达式
public interface RowMapping {
//将一行数据映射成一个实体对象
//任意的实体对象
Object mapper (ResultSet rs) throws SQLException;
}
package march.part0320.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JdbcTemplate {
public static void executeUpdate(String sql,Object ... preparedStatements) {
Connection connection = null;
connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
setPreparedStatements(preparedStatement,preparedStatements);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement,connection);
}
}
private static void setPreparedStatements(PreparedStatement preparedStatement,Object ... preparedStatements) {
if (!(null == preparedStatement || preparedStatements.length == 0)) {//有参数
for (int i = 0 ; i < preparedStatements.length ; i++) {
try {
preparedStatement.setObject((i + 1),preparedStatements[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public static List executeQuery (String sql , RowMapping rowMapping , Object ... params) {
List datas = new ArrayList();//返回任何一类的实体对象
//模板化的步骤
//1. 加载驱动
//2. 获取链接
Connection connection = null;
connection = JdbcUtil.getConnection();
//3. 获取SQL执行器
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
preparedStatement = connection.prepareStatement(sql);
//4. 执行SQL
setPreparedStatements(preparedStatement , params);
rs = preparedStatement.executeQuery();
//处理结果
while (rs.next()) {
//一行数据——>映射成实体对象
//User user = new User() 或Dept dept = new Dept()各种各样
//通用的Object object = new Object(),object没有set方法——>没有办法做映射
Object object = rowMapping.mapper(rs);
//实体对象添加到集合中
datas.add(object);
}
} catch (SQLException e) {
e.printStackTrace();
}
return datas;
}
}
测试:
package march.part0320.dao.impl;
import march.part0320.dao.UserDao;
import march.part0320.entity.User;
import march.part0320.util.DateUtil;
import march.part0320.util.JdbcTemplate;
import march.part0320.util.JdbcUtil;
import march.part0320.util.RowMapping;
import java.sql.*;
import java.util.List;
public class UserDaoImpl implements UserDao {
@Override
public void add(User user) {
String sql = "insert into t_user(t_username,t_pwd,t_createtime) values (?,?,now())";
JdbcTemplate.executeUpdate(sql,user.getUserName(),user.getPwd());
}
@Override
//希望做成模板
public User query(String userName, String pwd) {
String sql = "select t_username,t_pwd,t_createtime from t_user where t_pwd = ? and t_username = ?";
RowMapping rowMapping = rs -> {
User user = new User();
user.setUserName(rs.getString("t_username"));
user.setPwd(rs.getString("t_pwd"));
user.setCreateTime(DateUtil.strToDate(rs.getString("t_createtime") , "yyyy-MM-dd HH:mm:ss"));
return user;
};
List datas = JdbcTemplate.executeQuery(sql , rowMapping , pwd , userName);
if (datas.size() > 0) {
User user = (User) datas.get(0);
return user;
} else {
return null;
}
}
}
每次强转比较麻烦,引入范型
package march.part0320.util; import java.sql.ResultSet; import java.sql.SQLException; @FunctionalInterface//当一个接口中只有一个抽象方法时,就是一个函数式接口 //可以使用lambda表达式 public interface RowMapping{ //将一行数据映射成一个实体对象 //任意的实体对象 T mapper (ResultSet rs) throws SQLException; }
package march.part0320.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JdbcTemplate {
public static void executeUpdate(String sql,Object ... preparedStatements) {
Connection connection = null;
connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
setPreparedStatements(preparedStatement,preparedStatements);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement,connection);
}
}
private static void setPreparedStatements(PreparedStatement preparedStatement,Object ... preparedStatements) {
if (!(null == preparedStatement || preparedStatements.length == 0)) {//有参数
for (int i = 0 ; i < preparedStatements.length ; i++) {
try {
preparedStatement.setObject((i + 1),preparedStatements[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public static List executeQuery (String sql , RowMapping rowMapping , Object ... params) {
List datas = new ArrayList();//返回任何一类的实体对象
//模板化的步骤
//1. 加载驱动
//2. 获取链接
Connection connection = null;
connection = JdbcUtil.getConnection();
//3. 获取SQL执行器
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
preparedStatement = connection.prepareStatement(sql);
//4. 执行SQL
setPreparedStatements(preparedStatement , params);
rs = preparedStatement.executeQuery();
//处理结果
while (rs.next()) {
//一行数据——>映射成实体对象
//User user = new User() 或Dept dept = new Dept()各种各样
//通用的Object object = new Object(),object没有set方法——>没有办法做映射
T data = rowMapping.mapper(rs);
//实体对象添加到集合中
datas.add(data);
}
} catch (SQLException e) {
e.printStackTrace();
}
return datas;
}
}
使用:
package march.part0320.dao.impl;
import march.part0320.dao.UserDao;
import march.part0320.entity.User;
import march.part0320.util.DateUtil;
import march.part0320.util.JdbcTemplate;
import march.part0320.util.JdbcUtil;
import march.part0320.util.RowMapping;
import java.sql.*;
import java.util.List;
public class UserDaoImpl implements UserDao {
@Override
public void add(User user) {
String sql = "insert into t_user(t_username,t_pwd,t_createtime) values (?,?,now())";
JdbcTemplate.executeUpdate(sql,user.getUserName(),user.getPwd());
}
@Override
//希望做成模板
public User query(String userName, String pwd) {
String sql = "select t_username,t_pwd,t_createtime from t_user where t_pwd = ? and t_username = ?";
RowMapping rowMapping = rs -> {
User user = new User();
user.setUserName(rs.getString("t_username"));
user.setPwd(rs.getString("t_pwd"));
user.setCreateTime(DateUtil.strToDate(rs.getString("t_createtime") , "yyyy-MM-dd HH:mm:ss"));
return user;
};
List datas = JdbcTemplate.executeQuery(sql , rowMapping , pwd , userName);
if (datas.size() > 0) {
User user = datas.get(0);
return user;
} else {
return null;
}
}
}
测试 OK
再把executeQuery细分成两个方法
查询多个 selectList ----.等价于executeQuery
查询单个 selectOne ----- selectList中的第一个元素
package march.part0320.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JdbcTemplate {
public static void executeUpdate(String sql,Object ... preparedStatements) {
Connection connection = null;
connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
setPreparedStatements(preparedStatement,preparedStatements);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement,connection);
}
}
private static void setPreparedStatements(PreparedStatement preparedStatement,Object ... preparedStatements) {
if (!(null == preparedStatement || preparedStatements.length == 0)) {//有参数
for (int i = 0 ; i < preparedStatements.length ; i++) {
try {
preparedStatement.setObject((i + 1),preparedStatements[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public static List executeQuery (String sql , RowMapping rowMapping , Object ... params) {
List datas = new ArrayList();//返回任何一类的实体对象
//模板化的步骤
//1. 加载驱动
//2. 获取链接
Connection connection = null;
connection = JdbcUtil.getConnection();
//3. 获取SQL执行器
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
preparedStatement = connection.prepareStatement(sql);
//4. 执行SQL
setPreparedStatements(preparedStatement , params);
rs = preparedStatement.executeQuery();
//处理结果
while (rs.next()) {
//一行数据——>映射成实体对象
//User user = new User() 或Dept dept = new Dept()各种各样
//通用的Object object = new Object(),object没有set方法——>没有办法做映射
T data = rowMapping.mapper(rs);
//实体对象添加到集合中
datas.add(data);
}
} catch (SQLException e) {
e.printStackTrace();
}
return datas;
}
public static List selectList(String sql , RowMapping rowMapping , Object ... params) {
return executeQuery(sql , rowMapping , params);
}
public static T selectOne(String sql , RowMapping rowMapping , Object ... params) {
List datas = selectList(sql , rowMapping , params);
if (datas.size() > 0) {
return datas.get(0);
} else {
return null;
}
}
}
使用场景:
DeptDao接口中添加根据部门编号查询部门信息
查询所有的部门信息
package march.part0320.dao;
import march.part0320.entity.Dept;
import java.util.List;
public interface DeptDao {
void add (Dept dept);
Dept queryByNo(int deptNo);
List query();
}
DeptDaoImpl
package march.part0320.dao.impl;
import march.part0320.dao.DeptDao;
import march.part0320.entity.Dept;
import march.part0320.util.JdbcTemplate;
import march.part0320.util.RowMapping;
import java.util.List;
public class DeptDaoImpl implements DeptDao {
@Override
public void add(Dept dept) {
String sql = "insert into dept(deptno,dname,loc) values (?,?,?)";
JdbcTemplate.executeUpdate(sql,dept.getDeptno(),dept.getDname(),dept.getLoc());
}
@Override
public Dept queryByNo(int deptNo) {
String sql = "select deptno,dname,loc from dept where deptno = ?";
RowMapping rowMapping = rs -> {
Dept dept = new Dept();
dept.setDeptno(rs.getInt("deptno"));
dept.setDname(rs.getString("dname"));
dept.setLoc(rs.getString("loc"));
return dept;
};
return JdbcTemplate.selectOne(sql , rowMapping , deptNo);
}
@Override
public List query() {
String sql = "select deptno,dname,loc from dept";
RowMapping rowMapping = rs -> {
Dept dept = new Dept();
dept.setDeptno(rs.getInt("deptno"));
dept.setDname(rs.getString("dname"));
dept.setLoc(rs.getString("loc"));
return dept;
};
return JdbcTemplate.selectList(sql , rowMapping);
}
}
测试
package march.part0320.test;
import march.part0320.dao.DeptDao;
import march.part0320.dao.impl.DeptDaoImpl;
import march.part0320.entity.Dept;
public class TestDeptDao {
public static void main(String[] args) {
DeptDao deptDao = new DeptDaoImpl();
// deptDao.add(new Dept(81,"chating","L104"));
Dept dept = deptDao.queryByNo(30);
System.out.println(dept);
}
}
如何一个Dao的实现类中,只出现一次需要结果映射的,直接使用lambda表达式
如果多次使用,可以直接定义一个具体的RowMapping子类
package march.part0320.mapping; import march.part0320.entity.Dept; import march.part0320.util.RowMapping; import java.sql.ResultSet; import java.sql.SQLException; public class DeptRowMapping implements RowMapping{ @Override public Dept mapper(ResultSet rs) throws SQLException { Dept dept = new Dept(); dept.setDeptno(rs.getInt("deptno")); dept.setDname(rs.getString("dname")); dept.setLoc(rs.getString("loc")); return dept; } }
package march.part0320.dao.impl;
import march.part0320.dao.DeptDao;
import march.part0320.entity.Dept;
import march.part0320.mapping.DeptRowMapping;
import march.part0320.util.JdbcTemplate;
import march.part0320.util.RowMapping;
import java.util.List;
public class DeptDaoImpl implements DeptDao {
@Override
public void add(Dept dept) {
String sql = "insert into dept(deptno,dname,loc) values (?,?,?)";
JdbcTemplate.executeUpdate(sql,dept.getDeptno(),dept.getDname(),dept.getLoc());
}
@Override
public Dept queryByNo(int deptNo) {
String sql = "select deptno,dname,loc from dept where deptno = ?";
return JdbcTemplate.selectOne(sql , new DeptRowMapping() , deptNo);
}
@Override
public List query() {
String sql = "select deptno,dname,loc from dept";
return JdbcTemplate.selectList(sql , new DeptRowMapping());
}
}
测试。



