JDBC(7)—DAO
介绍:
DAO(Data Access Object):数据访问对象- 1.what:访问数据信息的类,包含了对数据的CRUD(create read、update、delete),而不包含业务相关的信息。
2.why:实现功能模块化,更有利于代码的维护和升级。 - 3.how:使用JDBC编写DAO可能会包含的方法。
- public void update(String sql, Object … objects)
- public T get(Class clazz, String sql, Object … objects)
- public List getForList(Class calzz, String sql, Object … objects)
public E getForValue(String sql, Object … objects)
版本:1.0,之后还会对DAO进行修改,这只是一个非常简单的介绍。
- 1.what:访问数据信息的类,包含了对数据的CRUD(create read、update、delete),而不包含业务相关的信息。
2.实例:
DAO层代码
public class DAO1_7 {
/**
* 1.更新操作,insert、update、delete操作都包含在其中。
* @param sql
* @param objects
*/
public void update(String sql, Object ...objects){
Connection conn = null;
PreparedStatement preparedstatement = null;
try {
conn = TestTools.getConnection();
preparedstatement = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
preparedstatement.setObject(i + 1, objects[i]);
}
preparedstatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(preparedstatement, conn);
}
}
/**
* 2.查询一条记录,返回对应的对象。
* @param clazz
* @param sql
* @param objects:占位符从1开始
* @return
*/
public <T> T get(Class<T> clazz,String sql,Object ...objects){
T entity = null;
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
try {
//1.获取Connection
conn = TestTools.getConnection();
//2.获取PreparedStatement
preparedstatement = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0; i < objects.length; i++){
preparedstatement.setObject(i + 1, objects[i]);
}
//4.进行查询,获取ResultSet对象
rs = preparedstatement.executeQuery();
//5.若ResultSet中有数据,准备一个Map<String,Object>:键:存放列的别名,值:存放列的值
if(rs.next()){
Map<String,Object> values = new HashMap<String,Object>();
//6.得到ResultSetMetaData对象。
rsmd = rs.getMetaData();
//7.处理ResultSet,把指针向下移动一个单位。(在判断是否有数据是已经移动,此处不在需要)
//8.ResultSetMetaData对象中得到结果集中有多少列
int columnCount = rsmd.getColumnCount();
//9.由ResultSetMetaData得到每一列的值,再由ResultSet得到具体每一列的值
for(int i = 0; i < columnCount; i++){
String columnLabel = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
//10.填充Map对象
values.put(columnLabel, columnValue);
}
//11.使用反射创建Class对应的对象
entity = clazz.newInstance();
//12.遍历Map对象,使用反射遍历填充对象的属性值,Map:key为属性名,value为属性值
for(Map.Entry<String, Object> entry : values.entrySet()){
String propertyName = entry.getKey();
Object value = entry.getValue();
TestTools.setFieldValue(entity, propertyName, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return entity;
}
/**
* 3.查询多条记录,返回对应的对象的集合。
* @param calzz
* @param sql
* @param objects
* @return
*/
public <T> List<T> getForList(Class<T> calzz,String sql,Object ... args){
List<T> list = new ArrayList<>();//用于返回多个对象
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
try {
//1.获取Connection连接
conn = TestTools.getConnection();
//2.获取PreparedStatement对象
preparedstatement = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0; i < args.length; i++){
preparedstatement.setObject(i + 1, args[i]);
}
//4.进行查询,获取ResultSet对象
rs = preparedstatement.executeQuery();
//5.若ResultSet中有数据,准备一个List<Map<String,Object>>:
//键:存放列的别名,值:存放列的值,其中一个Map对象对应一条记录,values用于存放
List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> map = null;
//6.得到ResultSetMetaData对象。
ResultSetMetaData rsmd = preparedstatement.getMetaData();
//7.处理ResultSet,使用while()循环。(在判断是否有数据是已经移动,此处不在需要)
while(rs.next()){
map = new HashMap<>();
//8.把每个列别名和列值取出来,存到Map对象中
for(int i = 0; i < rsmd.getColumnCount(); i++){
String columnName = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
map.put(columnName, columnValue);
}
//9.再把Map对象存到List中
values.add(map);
}
//12.判断List是否为空集合,若不空则便利List得到一个个Map对象,
//再把Map对象转化成Class参数对应的Object对象
T bean = null;
if(values.size() > 0){
for(Map<String, Object> m : values){
bean = calzz.newInstance();
for(Map.Entry<String, Object> entry : m.entrySet()){
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
//为类成员变量赋值。
TestTools.setFieldValue(bean, propertyName, propertyValue);
}
//13.把Object对象放入到list中
list.add(bean);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return list;
}
/**
* 4_1.功能:查询多条记录,返回对应的对象的集合。对以上3.方法进行的拆分。
*与上一致,其中对ResultSet对象之后的代码进行优化,包括每次循环都都要获取列别名进行优化修改。
* @param calzz
* @param sql
* @param objects
* @return
*/
public <T> List<T> getForLists(Class<T> calzz,String sql,Object ... args){
List<T> list = new ArrayList<>();//用于接收返回的多个对象
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
try {
//1.得到结果集
conn = TestTools.getConnection();
preparedstatement = conn.prepareStatement(sql);
for(int i = 0; i < args.length; i++){
preparedstatement.setObject(i + 1, args[i]);
}
rs = preparedstatement.executeQuery();
//-----------------修改
//2.处理结果集,得到Map的List,其中一个Map对象就是一条记录,Map中Key表示列别名,Value表示列值
List<Map<String, Object>> values = handleResultSetToMapList(rs);
//3.把Map的list转为Clazz对应的list,其中Map的Key表示Class的成员属性,Value表示成员属性的值
list = transfterMapListToBeanList(calzz, values);
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return list;
}
/**
* 4_2.处理结果集,获取Map的List,其中一条Map对象对应一条记录。
* @param rs
* @return
* @throws SQLException
*/
private List<Map<String, Object>> handleResultSetToMapList(ResultSet rs)
throws SQLException {
List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> map = null;
//---------------此处被修改。6.得到ResultSetMetaData对象。
List<String> columnLabels = getColumnLabels(rs);
while(rs.next()){
map = new HashMap<>();
//---------------此处被修改。8.把每个列别名和列值取出来,存到Map对象中
for(String columnName : columnLabels){
Object columnValue = rs.getObject(columnName);
map.put(columnName, columnValue);
}
values.add(map);
}
return values;
}
/**
* 4_3获取结果集所有的列别名,存到集合中,再返回集合。
* @param rs
* @return
*/
private List<String> getColumnLabels(ResultSet rs){
List<String> labels = new ArrayList<>();
try {
ResultSetMetaData rsmd = rs.getMetaData();
for(int i = 0; i < rsmd.getColumnCount(); i++){
labels.add(rsmd.getColumnLabel(i + 1));
}
} catch (SQLException e) {
e.printStackTrace();
}
return labels;
}
/**
* 4_4.
* @param calzz
* @param values
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
private <T> List<T> transfterMapListToBeanList(Class<T> calzz,
List<Map<String, Object>> values) throws InstantiationException,
IllegalAccessException {
List<T> result = new ArrayList<>();
T bean = null;
if(values.size() > 0){
for(Map<String, Object> m : values){
bean = calzz.newInstance();
for(Map.Entry<String, Object> entry : m.entrySet()){
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
//为类成员变量赋值。
TestTools.setFieldValue(bean, propertyName, propertyValue);
}
//13.把Object对象放入到list中
result.add(bean);
}
}
return result;
}
/**
* 返回某条记录的某一个字段的值或一个统计的值(一共有多少条记录等。),即:确定的某一行的某个字段的值,或者计算的值
* @param sql
* @param objects
* @return
*/
public <E> E getForValue(String sql, Object ... objects){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.得到结果集:该结果集应该只有一行,且只有一列
conn = TestTools.getConnection();
ps = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
ps.setObject(i + 1, objects[i]);
}
rs = ps.executeQuery();
if(rs.next()){
//2.取得结果
return (E) rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, ps, conn);
}
return null;
}
}
测试dao层代码
public class DAOTest_1_7 {
DAO1_7 dao = new DAO1_7();
//测试:DAO——update(String sql, Object ...objects)方法。
@Test
public void testUpdate() {
String sql = "insert into customers(name,age,birth,address) " +
"value(?,?,?,?)";
dao.update(sql, "刘飒","20",new Date(new java.util.Date().getTime()),"河南省");
}
//测试:DAO——get(Class<T> clazz,String sql,Object ...objects)方法。
@Test
public void testGet() {
String sql = "select * from customers where id = ?";
Customers customers = dao.get(Customers.class, sql, 12);
System.out.println(customers);
}
//测试:DAO——getForList(Class<T> calzz,String sql,Object ... args)方法。
@Test
public void testGetForList() {
String sql = "select FlowID ,Type , IDCard , ExamCard " +
", StudentName , Location , Grade from examStudent";
List<Student> student = dao.getForLists(Student.class, sql);
for(int i = 0; i < student.size(); i++){
System.out.println(student.get(i));
}
}
//测试:DAO——getForValue(String sql, Object ... objects)
@Test
public void testGetForValue(){
String sql = "select examCard from examstudent where FlowID = ?";
String examCard = dao.getForValue(sql, 33);
if(examCard == null){
System.out.println("查无信息!");
}else{
System.out.println(examCard);
}
sql = "select Count(*) from examstudent";
Object count = dao.getForValue(sql);
System.out.println("共有:"+count+"行");
}
}
JDBC(7)—DAO的更多相关文章
- 跟着刚哥学习Spring框架--JDBC(六)
Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要提供JDBC模板方式.关系数据库对象化方式.SimpleJdbc方式.事务管理来简 ...
- SSM框架之Mybatis(3)dao层开发
Mybatis(3)dao层开发 以实现类完成CRUD操作 1.持久层dao层接口的书写 src\main\java\dao\IUserDao.java package dao; import dom ...
- MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JDBC(14)—对DAO进行改进修改
结构: DAO2_7< T >(接口)->DAOTestImpl< T >(实现类)->CustomerDAO(继承的子类)->CustomerDAOTest ...
- JDBC(四)
1 Apache DBUtils框架 1.1 DBUtils简介 commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本非常低,并且使用db ...
- JDBC(9)—事务(Transaction)
数据库事务:在数据库中所谓事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态.为确保数据库中的数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这些 ...
- jdbc(MySQL)
1.连接数据库 2.使用配置文件 3.启用连接池 4.事务 JDBC WHAT? 用于执行 SQL 语句的 Java API WHY? 不需要了解每一种数据库连接操作方式 HOW? 加载驱动.获取连接 ...
- JavaWeb基础—JDBC(二)事务与批处理
一.批处理 这里给出PrepareStatement的示例,优点是可以发送预编译的SQL,缺点是SQL语句无法更换,但参数可以更换 批处理:多条语句的处理 mysql默认是关闭的,要打开需要在url后 ...
- JDBC(一)
1. JDBC介绍 JDBC(Java DataBase Connectivity),即Java数据库的连接.JDBC是一种用于执行SQL语句(DML,DDL,DQL)的Java API,可以为多 ...
随机推荐
- OA系统高性能解决方案(史上最全的通达OA系统优化方案)
序: 这是一篇针对通达OA系统的整体优化方案,文档将硬件.网络.linux操作系统.程序本身(包括web和数据库)以及现有业务有效结合在一起,进行了系统的整合优化.该方案应用于真实生产环境,部署完成后 ...
- jdbc驱动加载
使用sqlserver数据库时,加载驱动: Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Strin ...
- 强大的Js树型控件Dtree使用详解
http://www.lmwlove.com/ac/ID868 在学习文章之前,要学会看官方网站http://destroydrop.com/javascripts/tree.从官方页面你能知道:dt ...
- 最新 macOS Sierra 10.12.3 安装CocoaPods及使用详解
一.什么是CocoaPods 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序 ...
- 如何选取一个神经网络中的超参数hyper-parameters
1.什么是超参数 所谓超参数,就是机器学习模型里面的框架参数.比如聚类方法里面类的个数,或者话题模型里面话题的个数等等,都称为超参数.它们跟训练过程中学习的参数(权重)是不一样的,通常是手工设定的,经 ...
- Android GsmCellLocation.getCellLocation返回NULL
Android GsmCellLocation.getCellLocation返回NULL 1.首先 获取服务 telephonyManager =(TelephonyManager)getSyste ...
- 一次TIME_WAIT和CLOSE_WAIT故障和解决办法
昨天解决了一个curl调用错误导致的服务器异常,具体过程如下: 里头的分析过程有提到,通过查看服务器网络状态检测到服务器有大量的CLOSE_WAIT的状态. 在服务器的日常维护过程中,会经常用到下面的 ...
- 测试开发之Django——No7.Django模板中的过滤器
1.add 将参数添加到值. 例如: {{ value|add:"2" }} 如果value是4,那么输出将是6. 此过滤器将首先尝试将两个值强制转换为整数.如果失败,它将尝试将值 ...
- how to detect circles and rectangle?
opencv中对圆检测的函数为:HoughCircles(src_gray,circles,CV_HOUGHT_GRADIENT,1,src_gray.cols/8,200,100,0,0) circ ...
- python 全栈开发,Day67(Django简介)
昨日内容回顾 1. socket创建服务器 2. http协议: 请求协议 请求首行 请求方式 url?a=1&b=2 协议 请求头 key:value 请求体 a=1&b=2(只有p ...