1.JavaBean 本质是一个满足下面条件的Java类
2.mvc开发模式 (servlet+jsp + javabean的开模式)
3.三层结构开发
package cn.itcase.entity;
/**
* 联系人实体类
* @author Administrator
*实体注意事项:
*一、实体类的名字尽量和数据库的表的名字对应相同。
二、实体类应该实现java.io.Serializable接口。
三、实体类应该有个无参的构造方法。
四、实体类应该有个有参(所有的参数)的构造方法。
五、实体类有属性和方法,属性对应数据库中表的字段,方法主要有getter和setter方法。
六、实体类还应该有个属性serialVersionUID。
例如:private static final long serialVersionUID = -6125297654796395674L;
七、属性一般是private类型,方法为public类型,对于数据库自动生成的ID字段对应的属性的set方法为private。
*/
public class Contact {
private String id;
private String name;
private String gender;
private int age;
private String phone;
private String email;
private String qq;
/**
* get和set方法就是为了能以得到和设置实体类中的私有属性值,
* 而一个类中至少要有一个构造方法,当没有人为添加的时候,
* 编译器会自动加入一个隐式的无参构造方法,当有人为添加时,编译器就不会自动添加了。
* 无参构造方法的作用是为了比较方便的new出一个对象
*/
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
/*有参构造方法(构造器):初始化属性(成员变量/实例变量)
* Java初始化:个人理解定义代码执行顺序,面向对象中的概念
* 非静态成员的初始化,发生在任何方法(包括构造器)被调用之前。并且它们定义的顺序,决定了初始化的顺序
* */
public Contact(String id,String name, String gender,int age,String phone,String email,String qq){
super(); // 调用父类构造方法,这里调用的是无参构造方法
this.id =id;
this.name=name;
this.gender=gender;
this.age=age;
this.phone = phone;
this.email = email;
this.qq=qq;
}
/*创建对象的过程叫实例化对象
* 创建对象(new) 调用的是无参数的构造方法(无参构造器)
*
* 如果写了有参数的构造方法,必须显示的写出无参数的构造方法
*
* 如果没有有参构造方法则不一定要写出,因为Java 虚拟机会帮我们隐式的出来
*
*
* */
public Contact(){
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
* 重写toString的目的:
* 便于输出一些想要的信息
*
* 跳过set方法
*/
@Override
public String toString() {
return "Contact [id=" + id + ", name=" + name + ", gender=" + gender
+ ", age=" + age + ", phone=" + phone + ", email=" + email
+ ", qq=" + qq + "]";
}
}
/*
* 知识点复习:自定义类创建对象三个步骤:
* 1.自定义类
* Class 类名{
* 事物的公共属性 成员变量描述
* 事物的公共行为 函数描述
* }
*
* 2.通过自定义创建对象
* 类名 变量名 = new 类名():
*
* 3.访问(设置)对象的属性或者对象的功能
* 访问对象的属性:对象.属性名
* 设置对象的属性:对象.属性 = 数据 调用对象的功能: 对象.函数名();
*
* 封装:忽略内部具体实现,提供访问的方法 getXXX(), 提供设置的方法setXXX();
*
* 局部变量与成员变量定义位置上的区别:
* 成员变量是定义在方法之外,类之内的
* 局部变量是定义在方法之内的
*
* 作用上的区别:
* 成员变量的作用是描述一类事物的公共属性
* 局部变量的作用是提供一个变量给方法内部使用
*
* 生命周期的区别: 成员变量是默认的初始值
* 数据类型 默认初始值
* Boolean False Char‘\000’(空字符)
* Byte 0(byte)
* Short 0(Short)
* Int 0
* Long 0L
* Float 0.0f
* Double 0.0
* 局部变量是没有默认的初始值的,必须要先初始化才能使用。
*
*
* 构造函数
* 作用:给对应的对象进行初始化
*
* 构造函数的格式:
* 修饰符 函数名(形式参数){
* 函数体
* }
*
* 构造函数的说明:
* 构造函数 是没有返回值类型的
* 构造函数的函数名必须与类名相同
* 构造函数不是由手动调用,在创建对象是时jvm主动调用构造函数
* 如果一个类没有显示的写上一个构造方法时,java编译器会为该类添加一个无参构造函数
* 如果一个类显示的写上了一个构造方法,那么Java编译器则不会为该类添加一个无参的构造函数
* 构造函数可以在一个类中以函数重载的形式存在多个
*
* JDK提供一个Java开发工具(java.exe)给我们进行反编译
*
* javap 反编译的使用格式:
* javap -c -1 -private 类名
*
* java编译器添加的无参构造函数的权限修饰符 是什么
* 与类的权限修饰符是一致的。
*
* 构造函数与普通函数的区别:
* 返回值类型:
* 构造函数没有返回值类型
* 普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void
*
* 函数名
* 构造函数的函数名必须与类名相同
* 普通函数只要符合标识符的命名规则即可
*
* 调用方式
* 构造函数是在创建对象的时候由JVM调用
* 普通函数是由我们使用对象调用的,一个对象可以调用多次普通函数
*
* 作用不同
* 构造函数的作用是初始化一个对象
* 普通函数是用于描述一类公共事物的行为
*
* this关键字与super关键字
* this关键字:
* this关键字代表了所属函数的调用者对象 谁调用我 我就调用谁 this.qq =qq; 初始化成员变量
*
* this关键字的作用
* 如果存在同名成员变量与局部变量,在方法内部默认是访问局部变量的数据,可以通过this关键字指定访问成员变量的数据。
* 在一个构造函数中可以调用另外一个构造函数初始化对象
*
* this关键字调用其他构造函数的注意事项:
* this关键字调用其他构造函数,this关键必须要位于构造函数的第一个语句
* this关键字在构造函数中不能出现相互调用的情况,这是一个死循环
*
* this关键字要注意的事项:
* 存在同名成员变量与局部变量时,在方法内部访问的事局部变量(java 采用的是”就近原则“ 访问的)
* 如果在一个方法中访问了一个变量,该变量只存在成员变量的情况下,那么java编译器会在该变量的 前面添加this关键字。
*/
package cn.itcase.dao;
import java.util.List;
import cn.itcase.entity.Contact;
/**
* 存放crud操作 联系操作方法接口
*
* @author Administrator
*
*/
public interface ContactDao {
public void addContact(Contact contact); // 添加联系人
public void updateContact(Contact contact); // 修改联系人
public void deleteContact(String id); // 删除联系人
public List findAll(); // 查询所有联系人
public Contact findByid(String id); // 根据id编号查询联系人
public boolean checkContact(String name); //姓名重复检索
}
/*知识点复习:
*
*
* 一.static(静态 修饰符)
* static修饰成员变量:数据需共享给对象时,可以用static修饰成员变量
* 静态成员: 在类加载的时候,类加载完成,就分配完空间;直到类被卸载时空间被回收
* 非静态成员: 创建对象的时候分配空间; 对象变为垃圾空间被回收的时候被销毁
*
* 静态成员变量的访问方式
* 方式1: 使用对象进行访问
* 格式: 对象.变量名
*
* 方式2: 可以使用类名进行访问
* 格式: 类名.变量名;
*
* 注意:
* 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问
* 不要为方便访问数据而是用static修饰成员变量,只有成员变量数据是真正需要被共享的时候才使用static修饰。
*
* static修饰成员变量的使用场景:如果一个数据需要被所有对象共享时,使用static修饰成员变量
*
* static可以修饰成员函数
*
* static静态,修饰符)
* static修饰成员变量时:被static修饰的成员变量是共享数据
*
* 静态成员变量访问方式:
* 方式一:使用对象访问
* 对象.属性名
* 方式二:使用类名进行访问
* 类名.属性名
* 注意:
* 非静态成员变量不能使用类名进行访问,只能使用对象进行访问
* 不能为了访问方便而使用static修饰成员变量,一定该数据是共享数据 时才使用static修饰。
*
* 二.static修饰方法(静态的成员方法)
* 方式一: 对象.静态方法(函数)名();
* 方式二: 类.静态函数ming() 推荐使用
*
* 静态成员变量与非静态成员变量的区别
* 1. 作用上的区别:
* 1. 静态的成员变量的作用共享一个 数据给所有的对象使用。
* 2. 非 静态的成员变量的作用是描述一类事物的公共属性。
* 2. 数量与存储位置上的区别:
* 1. 静态成员变量是存储方法 区内存中,而且只会存在一份数据。
* 2. 非静态的成员变量是存储在堆内存中,有n个对象就有n份数据。
* 3. 生命周期的区别:
* 1. 静态的成员变量数据是随着类的加载而存在,随着类文件的消失而消失。
* 2.非静态的成员数据是随着对象的创建而存在,随着 对象被垃圾回收器回收而消失。
*
* 静态函数要注意的事项:
* 1. 静态函数是可以通过类名或者对象进行调用的,而非静态函数只能使用对象进行调用。
* 2. 静态的函数可以直接访问静态的成员,但是不能直接访问非静态的成员。
* 原因:静态函数是可以使用类名直接调用的,这时候可能还没有存在对象,
* 而非静态的 成员数据是随着对象 的存在而存在的。
*
* 3. 非静态的函数是可以直接访问静态与非静态的成员。
* 原因:非静态函数只能由对象调用,当对象存在的时候,静态数据老早就已经存在了,而非静态数据也随着对象的创建而存在了。
*
* 4. 静态函数不能出现this或者super关键字。
* 原因:因为静态的函数是可以使用类名调用的,一旦使用类名调用这时候不存在对象,而this关键字是代表了一个函数 的调用者对象,这时候产生了冲突。
*
*静态的数据的生命周期:静态的成员变量数据是优先于对象存在的。
*
*static什么时候修饰一个函数?
* 如果一个函数没有直接访问到非静态的成员时,那么就可以使用static修饰了。 一般用于工具类型的方法
*
*静态函数不能访问非静态的成员?
* 静态函数只要存在有对象,那么也可以访问非 静态的数据。只是不能直接访问而已。
*
* 分类
* 静态成员函数
* 静态函数
*
* static修饰的函数,被限定在本类的源文件中,不能被其他源文件的类调用
*
* 三.抽象类:
抽象类的应用场景:
我们在描述一类事物的时候,发现该种事物确实存在着某种行为,
但是这种行为目前是不具体的,那么我们可以抽取这种行为 的声明,但是
不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类。
抽象类的好处: 强制要求子类一定要实现指定的方法。
抽象类要注意的细节:
1. 如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象 的函数。。
2. 如果一个类出现了抽象的函数,那么该类也必须 使用abstract修饰。
3. 如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。
4. 抽象类可以存在非抽象方法,也可以存在抽象的方法.
5. 抽象类可以不存在抽象方法的。
5. 抽象类是不能创建对象的。
疑问:为什么抽象类不能创建对象呢?
因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象的对象
调用抽象方法是没有任何意义的。
6. 抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。
abstract不能与以下关键字共同修饰一个方法:
1. abstract不能与private共同修饰一个方法。
2. abstract 不能与static共同修饰一个方法。
3. abstract 不能与final共同修饰一个方法。
四.接口
接口:拓展功能的。
举例:电脑的usb接口.。。
接口的定义格式:
interface 接口名{
}
接口要注意的事项 :
1. 接口是一个特殊的类。
2. 接口的成员变量默认的修饰符为: public static final 。那么也就是说接口中的成员变量都是常量。
3. 接口中 的方法都是抽象的方法,默认的修饰符为: public abstract。
4. 接口不能创建对象。
5. 接口是没有构造方法的。
6. 接口是给类去实现使用的,非抽象类实现一个接口的时候,必须要把接口中所有方法全部实现。
实现接口的格式:
class 类名 implements 接口名{
}
类与接口之间关系: 实现关系。
接口与接口之间关系: 继承关系。
类与接口要注意的事项:
1. 非抽象类实现一个接口时,必须要把接口中所有方法全部实现。
2. 抽象类实现一个接口时,可以实现也可以不实现接口中的 方法。
3. 一个类可以实现多个接口 。
java不支持多继承(类),但支持多实现(接口)
* */
package cn.itcase.dao_imp;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import cn.itcase.dao.ContactDao;
import cn.itcase.entity.Contact;
import cn.itcase.util.XMLUtil;
/**
* 联系人接口实现类
*
* @author Administrator
*
*/
public class ContactDaoImp implements ContactDao {
/* 添加联系人 */
@Override
public void addContact(Contact contact) {
try {
File file = new File("c:/contact.xml");
Document doc = null;
Element rootElem = null;
if (!file.exists()) {
// 没有文件则创建文件
doc = DocumentHelper.createDocument();
rootElem = doc.addElement("ListContact");
} else {
// 存在文件,读取文件
doc = XMLUtil.getDocument();
// 存在文件,读取跟标签
rootElem = doc.getRootElement();
}
// 添加标签
Element contactElem = rootElem.addElement("contact");
/**
* 有系统生成且唯一的ID值,赋值给联系人
*/
String uuid = UUID.randomUUID().toString().replace("-", "");
// 設置id属性
contactElem.addAttribute("id", uuid);
// 添加标签及其内容
contactElem.addElement("name").setText(contact.getName());
contactElem.addElement("gender").setText(contact.getGender());
contactElem.addElement("age").setText(contact.getAge()+"");
contactElem.addElement("phone").setText(contact.getPhone());
contactElem.addElement("email").setText(contact.getEmail());
contactElem.addElement("qq").setText(contact.getQq());
// 从内存中写出数据到xml文件
XMLUtil.write2xml(doc);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 修改联系人
*/
@Override
public void updateContact(Contact contact) {
try {
// 1.读取文件
Document doc = XMLUtil.getDocument();
// 2.查询需要查询的id的联系人
Element contactElem = (Element)doc.selectSingleNode("//contact[@id='"+contact.getId()+"']");
// 3.修改内容
contactElem.element("name").setText(contact.getName());
contactElem.element("gender").setText(contact.getGender());
contactElem.element("age").setText(contact.getAge()+"");
contactElem.element("phone").setText(contact.getPhone());
contactElem.element("email").setText(contact.getEmail());
contactElem.element("qq").setText(contact.getQq());
// 4.从内存中写出文件到xml文件
XMLUtil.write2xml(doc);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 删除联系人
*/
@Override
public void deleteContact(String id) {
try {
//1.读取xml文件
Document doc = XMLUtil.getDocument();
//2.查询需要删除id的contact
Element contactElem = (Element)doc.selectSingleNode("//contact[@id='"+id+"']");
//删除标签
if(contactElem!=null){
contactElem.detach();
}
//3.把Document写出到xml文件
XMLUtil.write2xml(doc);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 查询所用联系人
*/
@Override
public List findAll() {
// 读取xml文件
Document doc = XMLUtil.getDocument();
//2.创建List对象
List list = new ArrayList();
// 3.读取contact标签
@SuppressWarnings("unchecked")
List conList = (List)doc.selectNodes("//contact");
for(Element e:conList){
//创建Contact对象
Contact c = new Contact();
c.setId(e.attributeValue("id"));
c.setName(e.elementText("name"));
c.setGender(e.elementText("gender"));
c.setAge(Integer.parseInt(e.elementText("age")));
c.setPhone(e.elementText("phone"));
c.setEmail(e.elementText("email"));
c.setQq(e.elementText("qq"));
//把Contact放入list中
list.add(c);
}
return list;
}
/**
* 根据id查询联系人
*/
@Override
public Contact findByid(String id) {
// 1.读取文件
Document doc = XMLUtil.getDocument();
// 2.查询id
Element e = (Element)doc.selectSingleNode("//contact[@id='"+id+"']");
// 3.根据id查询联系人
Contact c = null;
if(e!=null){
//创建Contact对象
c = new Contact();
c.setId(e.attributeValue("id"));
c.setName(e.elementText("name"));
c.setGender(e.elementText("gender"));
c.setAge(Integer.parseInt(e.elementText("age")));
c.setPhone(e.elementText("phone"));
c.setEmail(e.elementText("email"));
c.setQq(e.elementText("qq"));
}
return c;
}
public static void main(String[] args) {
//测试UUID
String uuid = UUID.randomUUID().toString().replace("-","");
System.out.println(uuid);
}
/**
* true 重复
* false 不重复
*/
@Override
public boolean checkContact(String name){
//查询name标签的内容与传入的值是否一致
Document doc = XMLUtil.getDocument();
Element nameElem = (Element)doc.selectSingleNode("//name[text()='"+name+"']");
if(nameElem!=null){
return true;
}else{
return false;
}
}
}
/*
*二.xml加强
Dom4j修改XML文档
写出xml文档:
XMLWriter writer = new XMLWriter()
writer.wrtite(doc);
增加:
DocumentHelper.createDocument() 增加新文档
Element.addElement("name"); 增加子标签
Element.addAtrribute(“name”,“value”) 增加属性
修改:
Attribute.setValue("value"); 修改属性值
Element.setText("value"); 修改文本内容
删除:
Element.detach(); 删除标签
Attribute.detach(); 删除属性
XPath技术: 快速找到xml元素(标签,属性,文本)
dom4j使用xpath:
List list = Element.selectNodes("xpath表达式"); 多个节点对象
Node node = Element.selectSingleNode("xpath表达式"); 一个节点对象
xpath表达式:
/ 表示根位置 或者 子标签
// 表示后代标签(不分层次结构)
* 表示所有元素
[ ] 表示条件
@ 表示选择属性
text() 表示选择文本
and 表示与条件
SAX解析: 原理: 加载一点,解析一点,处理一点,对内存要求不高!!!(基于事件)
SAXPasser 类:
parser(File file, DefaultHandler handler):该方法使用sax解析方式去解析xml文档
DefaultHandler类:重写该类中的一些方法,用于处理xml文档
startElement( .... String qName): 读到开始标签时调用
characterrs(char[] ch,int start,int length); 读到文本内容时调用(包括空格和换行)
endElement(.....String qName): 读到结束标签时调用
* */
package cn.itcase.test;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import cn.itcase.dao.ContactDao;
import cn.itcase.dao_imp.ContactDaoImp;
import cn.itcase.entity.Contact;
/*
* 联系人操作实现类的测试类
*/
public class TestContactDaoImp {
ContactDao operator = null;
/**
* 初始化对象实例
*/
@Before
public void init(){
operator = new ContactDaoImp();
}
@Test
public void testAddContact(){
Contact contact = new Contact();
//contact.setId("2");
contact.setName("张三2");
contact.setGender("男");
contact.setAge(20);
contact.setPhone("134222233333");
contact.setEmail("[email protected]");
contact.setQq("33334444");
operator.addContact(contact);
}
@Test
public void testUpdateContact(){
Contact contact = new Contact();
contact.setId("1"); //修改的ID
contact.setName("李四");
contact.setGender("女");
contact.setAge(30);
contact.setPhone("135222233333");
contact.setEmail("[email protected]");
contact.setQq("33334444");
operator.updateContact(contact);
}
@Test
public void testDeleteContact(){
operator.deleteContact("2");
}
@Test
public void testFindAll(){
List list = operator.findAll();
for (Contact contact : list) {
System.out.println(contact);
}
}
@Test
public void testFindById(){
Contact contact = operator.findByid("1");
System.out.println(contact);
}
@Test
public void testCheckContact(){
System.out.println(operator.checkContact("王五1"));
}
}
package cn.itcase.service;
/**
* web 操作接口
*/
import java.util.List;
import cn.itcase.entity.Contact;
import cn.itcase.exception.NameRepeatException;
public interface ContactService {
public void addContact(Contact contact)throws NameRepeatException; // 添加联系人
public void updateContact(Contact contact);//修改联系人
public void deleteContact(String id);//删除联系人
public List findAll(); //查询所有联系人
public Contact findById(String id);//根据编号查询联系人
}
package cn.itcase.service.imp;
import java.util.List;
import cn.itcase.dao.ContactDao;
import cn.itcase.dao_imp.ContactDaoImp;
import cn.itcase.entity.Contact;
import cn.itcase.exception.NameRepeatException;
import cn.itcase.service.ContactService;
/**
*
*
*/
public class ContactServiceImp implements ContactService {
ContactDao dao = new ContactDaoImp();// 多态:接口引用类型变量 执行 接口实现类
// 添加联系人
@Override
public void addContact(Contact contact) throws NameRepeatException {
// 执行业务逻辑 检查姓名是否重复
if (dao.checkContact(contact.getName())) {
// 姓名重复抛出异常
throw new NameRepeatException("姓名重复,不可使用");
}
// 如果姓名不重复则执行添加操作
dao.addContact(contact);
}
//修改联系人
@Override
public void updateContact(Contact contact) {
dao.updateContact(contact);
}
// 根据id删除联系人
@Override
public void deleteContact(String id) {
dao.deleteContact(id);
}
// 查询所有联系人
@Override
public List findAll() {
return dao.findAll();
}
// 根据id查询联系人
@Override
public Contact findById(String id) {
return dao.findByid(id);
}
}
/*
知识点梳理
一.多态
多态:一个对象具备多种形态。(父类的引用类型变量指向了子类的对象或者是接口 的引用类型变量指向了接口实现类的对象)
多态的前提:必须存在继承或者实现 关系。
动物 a = new 狗();
多态要注意 的细节:
1. 多态情况下,子父类存在同名的成员变量时,访问的是父类的成员变量。
2. 多态情况下,子父类存在同名的非静态的成员函数时,访问的是子类的成员函数。
3. 多态情况下,子父类存在同名的静态的成员函数时,访问的是父类的成员函数。
4. 多态情况下,不能访问子类特有的成员。
总结:多态情况下,子父类存在同名的成员时,访问的都是父类的成员,除了在同名非静态函数时才是访问子类的。
编译看左边,运行不一定看右边。
编译看左边:java编译器在编译的时候,会检查引用类型变量所属的类是否具备指定的成员,如果不具备马上编译报错。
多态的应用:
1. 多态用于形参类型的时候,可以接收更多类型的数据 。
2. 多态用于返回值类型的时候,可以返回更多类型的数据。
多态的好处: 提高了代码的拓展性。
二.多态中的数据转型
多态情况下不能访问子类特有的成员。
如果需要访问子类特有的成员,那么需要进行类型强制转换.
基本数据类型的转换
小数据类型-------->大的数据类型 自动类型转换
大数据类型--------->小数据类型 强制类型转换 小数据类型 变量名 = (小数据类型)大数据类型;
引用数据类型的转换
小数据类型--------->大数据类型 自动类型转换。
大数据类型--------->小数据类型 强制类型转换
类型转换最场景的问题: java.lang.ClassCastException。 强制类型转换失败
三.内部类
内部类:一个类定义在另外一个类的内部,那么该类就称作为内部类。
内部类的class文件名: 外部类$内部类. 好处:便于区分该class文件是属于哪个外部类的。
内部类的类别:
1. 成员内部类:
成员内部类的访问方式:
方式一:在外部类提供一个方法创建内部类的对象进行访问。
方式二:在其他类直接创建内部类的对象。 格式:外部类.内部类 变量名 = new 外部类().new 内部类();
注意: 如果是一个静态内部类,那么在其他类创建 的格式:
外部类.内部类 变量名 = new 外部类.内部类();
内部类的应用场景: 我们在描述A事物的时候,发现描述的A事物内部还存在另外一个比较复杂的事物B时候,
而且这个比较复杂事物B还需要访问A事物的属性等数据,那么这时候我们就可以使用内部类描述B事物。
比如: 人--->心脏
class 人{
血
氧气
等....
class 心脏{
}
}
内部类的好处:内部类可以直接访问外部类的所有成员。
内部类要注意的细节:
1. 如果外部类与内部类存在同名的成员变量时,在内部类中默认情况下是访问内部类的成员变量。
可以通过"外部类.this.成员变量名" 指定访问外部类的 成员。
2. 私有的成员内部类只能在外部类提供一个方法创建内部类的对象进行访问,不能在其他类创建对象了。
3. 成员内部类一旦出现了静态的成员,那么该类也必须 使用static修饰。
局部内部类: 在一个类 的方法内部定义另外一个类,那么另外一个类就称作为局部内部类。
局部内部类要注意的细节:
1. 如果局部 内部类访问了一个局部变量,那么该局部变量必须使用final修饰、
匿名内部类:没有类名的类就称作为匿名内部类。
匿名内部类的好处:简化书写。
匿名内部类的使用前提:必须存在继承或者实现关系才能使用。
匿名内部类一般是用于实参。
四.模板模式 工具类
模板模式 :解决某类事情的步骤有些是固定的,有些是会发生变化的,那么这时候我们可以为这类事情提供一个模板代码,从而提高效率 。
五.集合
Collection接口: 单列集合 集合的顶级父类
Collection提供的方法(list和set适用 list和set是Collection的子类)
增加:
1:add() 将指定对象存储到容器中
add 方法的参数类型是Object 便于接收任意对象
2:addAll() 将指定集合中的元素添加到调用该方法和集合中
删除:
3:remove() 将指定的对象从集合中删除
4:removeAll() 将指定集合中的元素删除
修改
5:clear() 清空集合中的所有元素
判断
6:isEmpty() 判断集合是否为空
7:contains() 判断集合何中是否包含指定对象
8:containsAll() 判断集合中是否包含指定集合
使用equals()判断两个对象是否相等
获取: 9:int size() 返回集合容器的大小
转成数组10: toArray() 集合转换数组
List接口: 有存储顺序, 可重复
ArrayList: 数组实现, 查找快, 增删慢
由于是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快
LinkedList: 链表实现, 增删快, 查找慢 由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素,
后一个元素记住前一个元素. 这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低 单线程使用
list集合的特有方法:
1:增加
void add(int index, E element) 指定位置添加元素
boolean addAll(int index, Collection c) 指定位置添加集合
2:删除
E remove(int index) 删除指定位置元素
3:修改
E set(int index, E element) 返回的是需要替换的集合中的元素
4:查找:
E get(int index) 注意: IndexOutOfBoundsException
int indexOf(Object o) // 找不到返回-1
lastIndexOf(Object o)
5:求子集合
List subList(int fromIndex, int toIndex) // 不包含toIndex
迭代器
Itreator 该接口是集合的迭代器接口类,定义了常见的迭代方法
1:boolean hasNext() 判断集合中是否有元素,如果有元素可以迭代,就返回true。
2: E next() 返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException
3: void remove()从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
Vector: 和ArrayList原理相同, 但线程安全, 效率略低 和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低 多线程使用
Set接口: 无存储顺序, 不可重复
HashSet 哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。
TreeSet 红-黑树的数据结构,默认对元素进行自然排序(String)。如果在比较的时候两个对象返回值为0,那么元素重复。
LinkedHashSet
Map: 键值对 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值
HashMap 采用哈希表实现,所以无序
TreeMap 可以对健进行排序
HashTable 底层是哈希表数据结构,线程是同步的,不可以存入null键,null值。效率较低,被HashMap 替代。
LinkedHashMap 底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
map特有方法
1、添加:
1、V put(K key, V value) (可以相同的key值,但是添加的value值会覆
盖前面的,返回值是前一个,如果没有就返回null)
2、putAll(Map extends K,? extends V> m) 从指定映射中将所有映射关
系复制到此映射中(可选操作)。
2、删除
1、remove() 删除关联对象,指定key对象
2、clear() 清空集合对象
3、获取
1:value get(key); 可以用于判断键是否存在的情况。当指定的键不存在的时候,返
回的是null。
3、判断:
1、boolean isEmpty() 长度为0返回true否则false
2、boolean containsKey(Object key) 判断集合中是否包含指定的key
3、boolean containsValue(Object value) 判断集合中是否包含指定的value
4、长度:
Int size()
六.流概念
高级流(字符流) 低级流(字节流)
Reader OutputStream
Writer Inputstream
其他流都由这几个流派生而来
对流进行操作时,必须把低级流转换为高级流
I/O流按类型分类
一.Memory
从/向内存数组读写数据:CharArrayReader,CharArrayWriter,ByteArrayInputStream,ByteArrayOutputStream
从/向内存字符串读写数据:StringReader,StringWriter,StringBufferInputStream,StringBufferOutStream
二.Pipe管道
实现管道的输入和输出(进程间通信):PipedReader,PipeWriter,PipedInputStream,PipedOutputStream
三.File文件流
对文件进行读写操作:FileReader,FileWriter,FileInputStream,FileOutputStream
四.ObjectSerialization
对象输入,输出:ObjectInputStream,ObjectOutputStream
五.DataConversion数据流
按基本数据类型读,写(处理的数据是Java的基本数据类型):DataInputStream,DateOutputStream
六.Printing
包含方便的打印方法:PrintWriter,PrintStream
七.Buffering 缓冲区
在读入,写出时 对数据进行缓存,以减少I/O的次数:BufferedReader,BufferedWriter,BufferedIputStream,BuffereOutputStream
八.Filtering 滤流
在数据进行读写时进行过滤:FilterReader,FilterWriter,FilerInputStream,FilterOutputStream
九.Concatenation
合并输入并把多个输入流连成一个输入流:SequenceInputStream
十.Conunting
在读入数据时对行记数:LineNumberReader,LineNumberInputStream
十一.Peeking Ahead
通过通过缓存机制进行预读:PushBackReader,PushBackInputStream
十二.Converting between Bytes and Characters
按照一定的编码/解码标准将字节流转换为字符流,或反向转换(Stream到Reader,Writer的转换类):InputStreamReader,OutputStreamWriter
*
* */
package cn.itcase.exception;
/**
* 自定义 姓名异常 继承 Exception
*
* @author Administrator
*
*/
public class NameRepeatException extends Exception {
private static final long serialVersionUID = 1L;
public NameRepeatException(String msg) {
super(msg);
}
}
/**
* throw 在方法体内部 创建异常处理
*
* throws 在方法上抛出异常
*
* try{可能出现异常的代码(捕获异常)}catch(Exception e){处理异常}
*
*/
package cn.itcase.util;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 模板模式 工具类
*
* @author Administrator
*
*/
public class XMLUtil {
/**
* 读取方法
* @return
*/
public static Document getDocument() {
try {
Document doc = new SAXReader().read(new File(
"c:/contact.xml"));
return doc;
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 数据从内存写出到xml文件的方法
*/
public static void write2xml(Document doc){
try {
FileOutputStream out = new FileOutputStream("contact.xml");
//输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
/*知识点梳理
一.xml基础
* 1)XML的作用
1.1 作为软件配置文件
1.2 作为小型的“数据库”
2)XML语法(由w3c组织规定的)
标签:
标签名不能以数字开头,中间不能有空格,区分大小写。有且仅有一个根标签。
属性:
可有多个属性,但属性值必须用引号(单引号或双引号)包含,但不能省略,也不能单 双混用。
文档声明:
encoding="utf-8": 打开或解析xml文档时的编码
注意:
保存xml文档时的编码 和 解析xml文档时的编码要保持一致,才能避免中文乱码问题!
3)XML解析
程序读取或操作xml文档
两种解析方式: DOM解析 vs SAX解析
DOM解析原理:一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容(标签,属性,文本,注释)。
Dom4j工具(基于DOM解析原理):
读取xml文档:
Document doc = new SAXReader().read("xml文件");
节点:
nodeIterator(); 所有节点
标签:
element("名称") 指定名称的第一个子标签对象
elementIterator("名称"); 指定名称的所有子标签对象
elements(); 所有子标签对象
属性:
attributeValue(“名称”) 指定名称的属性值
attribute("名称") 指定名称的属性对象
getName() 属性名称
getValue() 属性值
atributeIterator() 所有属性对象(Iterator)
attributes() 所有属性对象(List)
文本:
getText() 得到当前标签的文本
elementText("子标签名称") 得到子标签的文本
三.Schema约束 DTD约束 (了解知道有这个东西 能看懂约束)
*/
package cn.itcase.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcase.entity.Contact;
import cn.itcase.exception.NameRepeatException;
import cn.itcase.service.ContactService;
import cn.itcase.service.imp.ContactServiceImp;
public class AddContactServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.设置编码格式
request.setCharacterEncoding("utf-8");
//2.接收参数 getParameter(); 根据参数名获取参数值
String name = request.getParameter("name");
String gender = request.getParameter("gender");
String age =request.getParameter("age");
String phone = request.getParameter("phone");
String email = request.getParameter("email");
String qq = request.getParameter("qq");
// 3.封装成Contact对象
Contact contact = new Contact();
contact.setName(name);
contact.setGender(gender);
contact.setAge(Integer.parseInt(age));
contact.setPhone(phone);
contact.setEmail(email);
contact.setQq(qq);
ContactService service = new ContactServiceImp();
// 4.调用添加方法
try {
service.addContact(contact);
} catch (NameRepeatException e) {
// 自定义异常处理
request.setAttribute("msg", e.getMessage());
request.getRequestDispatcher("/addContac.jsp").forward(request, response);
return;
}
// 5.跳转到查询联系人页面
response.sendRedirect(request.getContextPath()+"/ListContactServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
/*
Servlet梳理
1.Servlet生命周期(重点)
构造方法: 创建servlet对象。默认情况下,第一次访问servlet对象时。只调用1次。
init方法(有参): 创建完servlet对象后调用。只调用1次。
注意: 会调用无参的init方法。
service方法: servlet提供服务的方法。每次发出请求调用。
注意: request对象 ,response对象
destroy方法: tomcat服务器停止或web应用重新部署,servlet对象销毁,destroy方法被调用。
2.ServletConfig对象
获取servlet的初始化参数:
getInitParameter("name ");
getInitParameterNames();
3.ServletContext对象
得到web应用路径:
context.getContextPath();
request.getContextPath(); 等价于上面的代码
得到web应用参数:
context.getInitParameter("name");
context.getInitParameterNames();
域对象:
context.setAttribute("name",Object): 保存数据
context.getAttribute("name") 得到数据
context.removeAttribue("name") 清除数据
转发
context.getRequestDispatcher("路径").forward(request,response);
request.getRequestDispacher("路径").forward(request,response); 等价于上面的代码
得到web应用中的资源文件
context.getRealPath("路径")
context.getResourceAsStream("路径");
*/
package cn.itcase.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcase.service.ContactService;
import cn.itcase.service.imp.ContactServiceImp;
/**
* 删除联系人逻辑
* @author Administrator
*
*/
public class DeleteContactServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在火狐浏览器中以Get方式提交带参数的数据,会重复提交两次。
System.out.println("刪除联系人");
//1.接收Id
String id = request.getParameter("id");
// 2.调用Service删除联系人的方法
ContactService service = new ContactServiceImp(); // 接口引用数据类型 执行 接口实现类 多态
service.deleteContact(id);
//3.跳转到查询联系人的页面
response.sendRedirect(request.getContextPath() + "/ListContactServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
/*
*
一.http协议:浏览器客户端和服务器端之间数据传输的格式规范
请求报文 浏览器->服务器端
HttpServletRequest对象: 请求对象。获取请求信息。
请求行:request.getMethod() request.getRequestURI/getRequestURL() request.getProtocol();
请求头: request.getHeader("name") request.getHeaderNames()
实体内容: request.getInputStream()
获取参数数据:(GET或POST)
request.getParameter("name") 一个值的参数
request.getParameterValues("name"); 多个值的参数
request.getParameterNames() 所有参数
响应报文 服务器->浏览器端
HttpServletResponse对象: 响应对象。设置响应信息。
响应行: response.setStatus();
响应头: response.setHeader("name","value")
实体内容:
(PrintWriter) response.getWriter().writer(); 字符内容
(OutputStream)response.getOutputStream().writer(); 字节内容
二会话管理: 管理浏览器和服务器之间的会话过程中产生的会话数据
1.Cookie技术: 会话数据保存在浏览器客户端。
Cookie核心的API:
2.1 在服务器端创建Cookie对象
Cookeie cookie = new Cookie("name","value");
2.2 把cookie发送给浏览器端(通过响应头:set-cookie)
response.addCookie(cookie);
2.3 浏览器带着cookie信息访问服务器(通过请求头:cookie),服务器得到cookie信息
Cookie[] cookies = request.getCookies();
局限:
1)只能保存字符串类型,不能保存中文
2)一个cookie不能超过4kb
2.Session技术:会话数据保存在服务器端。(内存)
Session核心的API:
3.1 创建或得到session对象
HttpSession session = request.getSession(); //创建或得到session对象
request.getSession(false); //得到session对象
3.2 会话数据保存session对象中,和得到会话数据
session.setAttribute("name",Object); 保存数据
session.getAttribute("name") 得到数据
注意:
1)session.setIntactiveInterval(时间); 设置session过期时间
2)session.invalidate() 手动销毁session对象
*
*/
}
package cn.itcase.servlet;
/**
* 显示所有联系人
*/
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcase.entity.Contact;
import cn.itcase.service.ContactService;
import cn.itcase.service.imp.ContactServiceImp;
public class ListContactServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.从xml中读取数据
ContactService service = new ContactServiceImp();
List list = service.findAll(); // 对象.方法名
//2.把结果保存到对象域中
request.setAttribute("contacts", list);
// 3.跳转到Jsp页面
request.getRequestDispatcher("/listContact.jsp").forward(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
/*
*
一.Jsp基础
Jsp的执行过程
tomcat服务器完成:jsp文件->翻译成java文件->编译成class字节码文件-> 构造类对象-> 调用方法tomcat的work目录下存放jsp运行时的临时文件!
Jsp语法:
1)jsp表达式:<%=变量或表达式%> 向浏览器输出变量或表达式计算的结果
2)jsp脚本: <% java代码 %> 执行java代码 原理:翻译到_jspService()方法中
3)jsp声明: <%! 变量或方法 %> 声明jsp的成员变量或成员方法
4)jsp注释: <%!-- jsp注释 --%> 用于注释jsp代码,不会翻译到java文件中,也不会执行。
jsp的三大指令
1.include指令:用于包含其他页面。原理:先合并再翻译,叫静态包含
2. page指令:告诉tomcat服务器如何把jsp文件翻译成java文件
language: 翻译的动态语言。
import: 类导入
jsp文件编码问题:
pageEncoding: 告诉tomcat服务器使用什么编码翻译jsp文件(jsp->java文件)
contentType: tomcat服务器发送给浏览器的数据编码(tomcat服务器->浏览器)
异常错误相关的:
errorPage: 指定当前jsp页面的错误处理页面。
isErorrPage: 指定当前页面是否为错误处理页面。false,不是错误处理页面,则不能使用 exception内置对象;true,是错误处理页面,可以使用exception内置对象。
session: 是否开启session功能。false,不能用session内置对象;true,可以使用session内 置对象。
buffer: jsp页面的缓存区大小。
isELIgnore: 是否忽略EL表达式。
3.taglib:导入JSTL标签库
二.jsp加深
Jsp的9大内置对象
内置对象 数据类型(复杂数据类型)
request HttpServletRequet
response HttpServletResponse
config ServletConfig
application ServletContext
exception Throwable
page Object
pageContext PageContext
out JspWriter
session HttpSession
Jsp的4个域对象
request
session
application
pageContext
作用范围:
pageContext : 处于当前jsp页面中有效的!!
request: 处于同一个请求中有效的!!
session: 处于同一个会话中有效的!
application: 处于同一个web应用中有效的!
EL表达式
替代jsp表达式,用于向浏览器输出域对象中的变量值和表达式计算的结果。
语法:
${变量}
1 输出普通字符串: ${name}
2 输出对象属性: ${student.name} 注意: .name 相当于 .getName()方法
3 输出List集合: ${list[0].name } 注意: [0] 相当于 get(下标)方法
4 输出map集合: ${map[key].name} 注意: [key]相当于get(key)方法
jsp标签
替代jsp脚本,用于在jsp页面中执行java代码
内置标签:
request.getRequesetDipsacher("/路径").foward(request,response);
参数标签 ?name=eric
包含其他页面 ,动态包含
静态包含: 先合并再翻译。不能传递参数
动态包含: 先翻译再合并。可以传递参数
jstl标签库 (java标准标签库)
使用步骤:
1)确保jstl支持的jar包存在于项目中
2)在jsp页面中导入标签库
<%@taglib uri="标签库声明文件tld文件的标记" prefix="前缀"%>
3)使用标签库中的标签
核心标签库:
保存数据到域对象中
从域中取出数据
单条件判断
+ + 多条件判断
遍历数据
遍历特殊字符串
重定向
*/
package cn.itcase.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcase.entity.Contact;
import cn.itcase.service.ContactService;
import cn.itcase.service.imp.ContactServiceImp;
public class QueryContactServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接收id
String id = request.getParameter("id");
// 调用service 根据id查询联系
ContactService service = new ContactServiceImp();
Contact contact = service.findById(id);
// 把查询结果保存到request域中
request.setAttribute("contact",contact);
//跳转到修改联系人的页面
request.getRequestDispatcher("/updateContact.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
doGet(request,response);
}
}
package cn.itcase.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcase.entity.Contact;
import cn.itcase.service.ContactService;
import cn.itcase.service.imp.ContactServiceImp;
public class UpdateContactServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 1.接收参数
String id = request.getParameter("id");
String name = request.getParameter("name");
String gender = request.getParameter("gender");
String age = request.getParameter("age");
String phone = request.getParameter("phone");
String email = request.getParameter("email");
String qq = request.getParameter("qq");
// 封装成Contact对象
Contact contact = new Contact();
contact.setId(id);
contact.setName(name);
contact.setGender(gender);
contact.setAge(Integer.parseInt(age));
contact.setPhone(phone);
contact.setEmail(email);
contact.setQq(qq);
// 2.调用service修改联系人的方法
ContactService service = new ContactServiceImp();
service.updateContact(contact);
// 3.跳转到查询联系人的页面
response.sendRedirect(request.getContextPath() + "/ListContactServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
addContact.jsp
<%@ page language="java" import="java.util.*,cn.itcase.entity.*"
pageEncoding="utf-8" errorPage="error.jsp" isErrorPage="true" session="true"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
addcontact
添加联系人
北京时间:
<%@ page language="java" import="java.util.*,cn.itcase.entity.*"
pageEncoding="utf-8" errorPage="error.jsp" isErrorPage="true"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
查询所有联系人
查询所有联系人
编号
姓名
性别
年龄
电话
邮箱
QQ
操作
${varSta.count }
${con.name }
${con.gender }
${con.age }
${con.phone }
${con.email }
${con.qq }
修改
删除
[添加联系人]
updateContact
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"
errorPage="error.jsp" isErrorPage="true"
%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
修改联系人
修改联系人
截图