实训--day05orm简单映射及web基本知识

来源:互联网 发布:淘宝店招在线设计 编辑:程序博客网 时间:2024/06/07 04:10

orm简单映射

逻辑好烦,而且一些关于堆栈的东西好复杂,没弄清底层的代码,只有祭出代码,以便后续的复习。

和昨天的jdbc相比,就是把数据库和javabean连接起来了。

javabean和注解以及jdbc工具类的内容跟昨天的是一样一样的,所以就不再放上去了。

orm封装类:

import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.math.BigDecimal;import java.math.BigInteger;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;import com.xishiyou.shixun.annotation.Colunm;import com.xishiyou.shixun.annotation.ID;import com.xishiyou.shixun.annotation.Table;public abstract class PODao extends JDBCUtils{static ResultSet resultSet=null;@SuppressWarnings({ "unchecked"})public static List<Object> getList(Object obj) throws Exception{//1:定义一个StringBuffer来拼接需要用于查询的sql语句StringBuffer sb=new StringBuffer();//2:拼接sql语句前面固定的部分sb.append("select * from ");//3:获得需要映射的对象的class对象Class<Object> clazz=(Class<Object>) obj.getClass();//4:判断那个类上面是否存在注解,如果不存在,则抛出定义的异常。if(!clazz.isAnnotationPresent(Table.class)){throw new Exception(clazz.getName()+"没有添加注解");}//5:如果存在注解,纳闷注解的内容就是需要拼接的表名else{Table table = clazz.getAnnotation(Table.class);sb.append(table.name());}String sql=sb.toString();System.out.println(sql);//6:对象中的所有属性就是表中的列,所以通过class对象获得所有的属性Field [] fields=clazz.getDeclaredFields();//7:如果属性存在,则执行sql语句。if(fields!=null && fields.length>0 ){//此处的lists也是必须要定义,如果不这样写,而是写null,就必须把那边关于list的全部注释掉,具体原因我不是很懂。List<Object> lists=new ArrayList<>();resultSet=executeQuery(sql,lists);}//8:这个方法的作用是进行po关系映射,即我们希望把数据库中的列和我们的对象的属性进行一个映射,//所以定义下面这个转换方法,把数据库中的每一行的列都和属性对应,然后把所有对象存入一个list集合中List<Object> returnList=convertValues(clazz,fields);//9:三元运算符判断上面的方法返回的值return returnList.isEmpty() ? null:returnList;//return null;}//9:实现数据库中的列和对象的属性的转换的方法:private static List<Object> convertValues(Class<Object> clazz, Field[] fields) throws Exception {//10:定义一个返回值类型的参数,后面用于存储需要返回的东西。List<Object> list=new ArrayList<>();//11:对我们需要映射的类进行实例化处理。//12:循环获取数据库中每一行的数据while(resultSet.next()){//这里原本我是在外面做的操作,但是会报错,我把它调在里面之后就没有错了。Object temp=clazz.newInstance();//13:遍历前面获取到的属性集合里面的内容for(Field field:fields){//14:因为数据库里面的内容都是可以改变的,所当和对象的属性映射的时候,被final或者static修饰的属性就不能进行映射。int modifiers=field.getModifiers();if(modifiers==Modifier.FINAL || modifiers==Modifier.STATIC){continue;}//15:定义一个String来存放数据库中的列名String colunm=null;//16:属性上的注解的内容就是数据库中的列名,列分为主键和一般的列//如果是主键,则把列名设置为主键的名字if(field.isAnnotationPresent(ID.class)){//获取属性上面注解的内容,设置为主键名colunm=field.getAnnotation(ID.class).name();//System.out.print(colunm+":");//用于测试的打印}//17:如果是一般列,则把列名设置为一般列的名字else if(field.isAnnotationPresent(Colunm.class)){//获取属性上面注解的内容,设置为列名colunm=field.getAnnotation(Colunm.class).name();//System.out.print(colunm+":");//用于测试的打印}if(colunm!=null){//18:设置属性的访问权限field.setAccessible(true);//19:获得数据库中存储的列对应的值Object object=convertObject(resultSet.getObject(colunm));//20:定义方法对特殊的数据进行处理//object=convertObject(object);//21:操作属性:为属性设置值field.set(temp, object);//System.out.println(field.get(temp));//用于测试的打印}}list.add(temp);temp=null;//System.out.println();用于测试的打印}return list;}private static Object convertObject(Object object) {if(object instanceof BigDecimal){return ((BigDecimal) object).floatValue();}else if(object instanceof BigInteger){return ((BigInteger) object).intValue();}return object;}}
我不知道老师为什么要把这个类定义为抽象类,可以是真实开发中需要这样做吧,所以为了使用其中的方法,必须有一个类继承这个类,才能实例化对象来使用方法。

还有,我在写代码的时候遇到了两个问题

1:在调用工具类的查询方法的时候,传入一个集合,如果我直接在new 一个ArrayList放进去或者放一个null,会报空指针,

只有这样才不没那么多报错。

List<Object> lists=new ArrayList<>();resultSet=executeQuery(sql,lists);

2:第二个问题我没找到,是同学帮我找到的。

Object temp=clazz.newInstance();
这个我的初始化如果方外while循环外面,就会报错,我不知道原因,只是放进循环里面就不会报错了。我也很方啊。

public class BaseDao extends PODao {public BaseDao() {super();}}
测试类:

import java.util.List;public class Test {@SuppressWarnings("static-access")public static void main(String[] args) throws Exception {BaseDao base=new BaseDao();List<Object> lists=base.getList(new UserInfo());for(Object list:lists){System.out.print(((UserInfo) list).getId()+":");System.out.println(((UserInfo) list).getName());}        }}

真搞不懂,为什么要把数据库的那些东西放在注解里面,取出的步骤那么麻烦,也不占多少内存啊。。。


web基本知识:

web服务器开发
架构?
B/S:浏览器服务器
C/S:客户端服务器


两者的区别:
1:安装方式:c/s需要下载客户端,b/s不需要
2:升级方式:c/s没戏升级的时候需要下载客户端,b/s只需要服务器升级即可
3:使用方式:c/s移动端使用的,b/s只能是浏览器


web服务器:
1:http协议的主要特点
1)遵循请求/响应模式
2)无连接:每次的连接只处理一个请求,服务器处理客户端的请求并接收到客户端的响应后断开连接。
3)无状态:服务器对事物的处理没有记忆能力,缺乏状态意味着如果后续的处理需要前面的信息,则需要重新传一次,这样会增加传输的数据量


2:web服务器存在的缺陷
1)只能加载静态的网页内容,不能加载动态的资源
2)如果要实现动态的资源,则必须在容器中添加应用辅件(在容器中进行注册,根据参数进行查找与运行)


3:服务器编程技术
1)CGI:公共网关接口,优点是通过c,python,php等进行编写,缺点是它把每一次的请求当做一个进程来处理,这样会极大的限制服务器的访问量,并浪费了服务器的资源
2)基于微软的asp和.net技术
3)基于Java的servlet和jsp技术,该技术弥补了CGI的缺点。servlet依附于一个主进程中或者是父程序中,它是把每一个请求当做一个线程来处理。

总结:以前代码报错都是些自己慢慢改的出来的,现在涉及更深层次的内存之类的错误,我真的无能为力了。。。

记录一个考点:

栈:存放基本数据类型和对象引用名称
堆:存放实际对象

& 和 && 的区别:

都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,
否则,只要有一方为false,则结果为false。
1)&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,
例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException
如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长
2)&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,
我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。