【Python每日一练】JSON和CSV处理练习

JSON练习

3.1 导入population.json数据,并格式化输出中国China的人口数据。

下载:population.json

CSV联系

3.2 使用with导入population.csv数据,并输出中国China的人口数据。

下载:population.csv

答案

3.1

import json
fileURL = "population.json"
r = open(fileURL,"r")
popData = json.load(r)
for country in popData:
    if country["Country"] == "China":
        country = json.dumps(country,indent=1)
        print(country)

3.2

import csv
fileURL = "population.csv"
with open(fileURL) as f:
    f_csv = csv.reader(f)
    for row in f_csv:
        if row[0] == "China":
            print(row)

【Python每日一练】文件IO和函数

Python文件IO练习

2.1 创建文件夹和文件

创建文件夹fileset,并在fileset里面生成20个.txt文件。
Txt文件名为1-20.txt,txt内的内容为当天时间+文件名。

2.2 文件IO

将上面20个文件的内容合并到一个新文件all.txt中。
并将all.txt中的内容逐行输出。

2.3 文件删除和函数

定义一个deleteDir函数,删除上面的fileset文件夹,连同里面的所有文件。

答案

2.1

import os
import datetime
folderUrl = "fileset"
if not os.path.exists(folderUrl):
    os.mkdir(folderUrl)
for i in range(1,21):
    f = open("fileset\\"+str(i)+".txt","w")
    f.write(str(datetime.datetime.now())+" "+str(i)+".txt")
    f.close()

2.2

import os
folderUrl = "fileset"
fileSet = os.listdir(folderUrl)
w = open("all.txt","w")
for fileName in fileSet:
    r = open(folderUrl + "\\" + fileName, "r")
    w.write(r.read()+"\r\n")
    r.close()
w.close()
r = open("all.txt","r")
for line in r:
    print(line)
r.close()

2.3

import os
def deleteDir(folderURL):
    for fileName in os.listdir(folderURL):
        os.remove(folderURL+"\\"+fileName)
    os.rmdir(folderURL)

deleteDir("fileset")

【Python每日一练】基本语法练习

为啥要练?

作为一名coder,应该尽可能多的了解各种主流编程语言和技术体系。然而,无论这个coder多牛,其在实际工作中常用的技术和语言也是有限的。然而,任何一门语言和技术,无论你曾经精通到何种程度,放下几个月不用,再拿起来也会生疏。
所以呢,对于自己喜欢的语言和技术,我喜欢总结一些简单的练习题,有空就简单的联系一下,这样可以保持对这门语言或技术的热度。

【Python基本语法】练习题

1.1 创建一个拥有20个元素的随机列表并输出。

随机列表的元素为1-1000间的整数。
随机列表输出时采用升序右对齐输出。

1.2 创建一个拥有20个元素的随机元祖并输出。

随机元祖的元素为1-1000位随机数字+1随机英文字母组合。
随机元祖输出时升序排序并采用右对齐输出。

1.3 创建一个拥有20个键值对的随机字典并输出。

随机字典的键为1-1000的随机整数,随机字典的值为4位随机英文字母组合。
随机字典键输出时按键升序排序,并采用左对齐方式。

1.4 创建两个随机集合,并计算输出。

创建一个拥有50个元素的随机集合A。随机集合元素内容为1-100的随机整数。
创建一个拥有50个元素的随机集合B。随机集合元素内容为1-100的随机整数。

计算并输出:
集合A
集合B
集合A-集合B
集合B-集合A
集合A+集合B

答案:

1.1

import random
listVar = []
for i in range(0,20):
    listVar.append(random.randint(1,1000))
listVar.sort()
for i in range(0,20):
    print((str(listVar[i])).rjust(4))

1.2

import random
import string
varList = []
for i in range(0,20):
    randomChar = string.ascii_lowercase
    varList.append(str(random.randrange(1,1000)) + random.choice(randomChar))
varList.sort()
varTuple = tuple(varList)
for i in range(1,20):
    print(varTuple[i].rjust(5))

1.3

import random
import string
randomDict = {}
while 1==1:
    key = random.randint(1,1000)
    value = random.choices(string.ascii_uppercase,k=4)
    randomDict[key] = "".join(value)
    if len(randomDict) == 20:
        break
for key in sorted(randomDict):
    print(str(key).rjust(4) + "->" + randomDict[key])

1.4

import random
aSet = set()
bSet = set()
while 1==1:
    aSet.add(random.randint(1,100))
    if len(aSet) == 50:
        break
while 1==1:
    bSet.add(random.randint(1,100))
    if len(bSet) == 50:
        break
print(aSet)
print(bSet)
print(aSet-bSet)
print(bSet-aSet)
print(aSet.union(bSet))

VMWare WorkStation和VMware vSphere Hypervisor的用途和区别

前言

提起VMWare,我们都知道是虚拟机。
然而打开VMWare的网站,各种产品琳琅满目,每种产品都能够满足不同的功能。
对于我们而言,最常用的两个产品莫过于VMWare WorkStation和VMware vSphere Hypervisor。
那么这两个产品分别有什么用途?又有什么区别呢?

VMWare WorkStation

应用场景一:

我们在学习Linux的时候,经常需要在机器上安装Linux操作系统,很多时候还需要安装不止一个Linux发行版。当然,我们可以给电脑安装双系统或多系统,但这种方式的弊端很明显:每次使用不同的操作系统都要重启电脑。
这时候我们就可以使用VMWare WorkStation在Windows操作系统里面安装多个Linux虚拟机,这样就可以在操作系统间自由切换了。

应用场景二:

在我们学习负载均衡和分布式的时候,需要几台电脑去模拟分布式环境。当然,我们可以用多台电脑连接网线去模拟这种拓扑环境,但这种方法一方面硬件费用高,另一方面也确实操作繁琐。
这时候我们就可以使用VMWare WorkStation在Windows操作系统里面开启多个虚拟机,每个虚拟机就相当于一台电脑,这样就可以模拟负载均衡和分布式环境了。

VMware vSphere Hypervisor

应用场景:

我们购买了一台服务器,性能很高,比如32GB的内存,10T的硬盘。
有四个项目想要使用这台服务器,当然,你可以给这台服务器安装一个Windows Server或Linux操作系统,然后将这个四个项目都放在一个操作系统下,四个项目彼此共享32GB内存和10T的空间和CPU资源。
这种方式的弊端很明显,四个项目的管理者都可以登录服务器查看和调用服务器资源,项目A的管理者在操作项目A的时候,很有可能对其它项目造成影响。
VMware vSphere Hypervisor实际上就是将服务器资源进行虚拟分割,每个分割的服务器资源都可以单独安装操作系统,操作系统间互不影响。

总结

两者的区别可以粗略理解如下:

  1. VMware WorkStation是为台式机做虚拟化使用的;而VMware vSphere Hypervisor是为服务器虚拟化使用。
  2. 如果要在某操作系统中再进行虚拟化,则使用VMware WorkStation;如果要直接在服务器资源上进行虚拟化,则使用VMware vSphere Hypervisor。

终于来了!SSM整合!第二个SpringMVC撰写!

第一步:Spring整合MyBatis

请参考:http://www.leonwish.com/archives/88

第二步:将SpringMVC整合进入Spring和MyBatis

  1. 修改UserServiceImpl.java
package com.royotech.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.royotech.dao.PersonDAO;
import com.royotech.entity.Person;
import com.royotech.service.UserService;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private PersonDAO personDAO;

    @Override
    public List<Person> select() {
        return personDAO.selectAll();
    }
}
  1. applicationContext.xml头部增加scanner语句。
<context:component-scan base-package="com.royotech.service"></context:component-scan>
  1. web.xml增加filter
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
  1. 撰写controller
package com.royotech.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.royotech.entity.Person;
import com.royotech.service.UserService;

@Controller //作用:将当前类的对象交给Spring工厂创建
@RequestMapping("user")   //请求路径
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("select") //请求路径
    public String select(Model model) {
        List<Person> listPerson = userService.select();
        model.addAttribute("listPerson",listPerson);
        return "forward:/list.jsp";
    }
}
  1. 撰写list.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome!</title>
</head>
<body>
    <c:forEach var="person" items="${listPerson}">
        ${person.id},${person.name},${person.birthday},${person.telephone},${person.address}<br/>
    </c:forEach>
</body>
</html>
  1. 大功告成,测试结果如下:
    file

为什么要用SpringMVC?撰写第一个SpringMVC程序

为什么要使用SpringMVC?

SpringMVC作为SSM三剑客中的一个S,其盛行有着以下几方面原因:

  1. Struts2的没落。
    在SSM之前,我们经常说SSH - Struts2、Spring、Hibernate;而现在谈SSM,是指SpringMVC、Spring、MyBatis。SpringMVC是活生生的把Struts2挤下了神坛。Struts2没落的原因有很多,有其重大安全漏洞导致的客户流失,也有框架使用繁琐不适合当代快速开发趋势的原因。
  2. 与Spring的血缘关系。
    SpringMVC与Spring之间有着天然的血缘关系,因此SpringMVC与Spring的结合更紧密,兼容性更好,整合也更容易。
  3. 开发更高效。
    当代程序语言除了“拼性能”外,还要“拼优美”。SpringMVC相较于Struts2而言其程序架构更加优美,开发时代码也更加优美。

说了这么多,还是让我们写一个最简单的SpringMVC程序,看看他的优美之处在哪里?

撰写第一个SpringMVC程序

第一步:添加依赖。

我们依然是基于Maven开发,运行SpringMVC程序的最小依赖如下:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
    </dependency>

这个不用记忆,固定模式。

第二步:配置web.xml

然后配置下WEB-INF目录下的web.xml,这些内容也不用记忆,也是固定模式。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

第三步:编写Controller

创建Controller包,并在下面建立UserController.java
扫盲一下:
struts和SpringMVC本质上都是对Java Servlet功能的封装和集成。
struts2地址习惯以.action结尾,控制器名字习惯以XxxAction方式命名。
SpringMVC地址习惯以.do结尾,控制器名字习惯以XxxController方式命名。

package com.royotech.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller //作用:将当前类的对象交给Spring工厂创建
@RequestMapping("user")   //请求路径
public class UserController {
    @RequestMapping("select") //请求路径
    public String select() {
        return "forward:/list.jsp"; //forward转发到的位置
    }
}

第四步:配置mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans   xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置SpringMVC启用注解,哪个包下的内容要使用SpringMVC,就在这里写哪个包的位置 -->
    <context:component-scan base-package="com.royotech.controller"></context:component-scan>
</beans>

第五步:大功告成,测试一下!

新建userController跳转到的list.jsp文件:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome!</title>
</head>
<body>
    Hello!SpringMVC!
</body>
</html>

在浏览器中输入:
http://localhost:8080/JAVA_ALL/user/select.do
注意:

  1. JAVA_ALL是项目名称,区分大小写。
  2. SpringMVC的Controller默认以.do结尾,不加.do访问不到。
    运行结果如下:
    file

第三个Spring程序撰写,整合Spring和MyBatis

MyBatis项目环境搭建及第一个MyBatis程序

请参考:http://www.leonwish.com/archives/59

搭建Spring开发环境

请参考:http://www.leonwish.com/archives/79

第一个Spring程序的撰写,理解SpringIOC

请参考:http://www.leonwish.com/archives/81

第二个Spring程序的撰写,理解SpringAOP

请参考:http://www.leonwish.com/archives/86

第三个Spring程序的撰写,整合Spring和MyBatis

第一步:添加依赖。

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.3</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>

第二步:建表、定义对应的实体类
数据库名:java_all,表名:t_person,表结构如下:
file

在entity包下新建实体类Person

package com.royotech.entity;

import java.io.Serializable;

public class Person implements Serializable{
    private Integer id;
    private String name;
    private String birthday;
    private String telephone;
    private String address;

    public Person() {
        super();
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", birthday=" + birthday + ", telephone=" + telephone
                + ", address=" + address + "]";
    }
}

第三步:DAO包下定义DAO接口

package com.royotech.dao;

import java.util.List;

import com.royotech.entity.Person;

public interface PersonDAO {
    public List<Person> selectAll();
}

第四步:applicationContext.xml下增加对应的bean标签

    <!-- 1.创建数据源(之前在mybatis-config.xml中配置) -->
    <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/java_all?useUnicode=true&characterEncoding=utf8"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123123"></property>
    </bean>
    <!-- 2.创建SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="ds"></property>
        <!-- 相当于mybaits-config.xml中的mapper注册,可以使用通配符* -->
        <property name="mapperLocations" value="classpath:mappers/*Mapper.xml"></property>
        <property name="typeAliasesPackage" value="com.royotech.entity"></property>
    </bean>
    <!-- 3.创建DAO对象 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 提供DAO接口包名,自动创建该包下所有DAO接口的实现类对象 -->
        <!-- DAO类名的首字母小写,就是从工厂中获取该接口对应实现类对象的id -->
        <property name="basePackage" value="com.royotech.dao"></property>
    </bean>

第五步:在view包下建立SelectPersonSpringMyBatis对象

package com.royotech.view;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.royotech.dao.PersonDAO;
import com.royotech.entity.Person;

public class SelectPersonSpringMyBatis {    
    public static void main(String[] args) throws Exception{
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        PersonDAO personDAO = (PersonDAO)ac.getBean("personDAO");
        List<Person> listPerson = personDAO.selectAll();
        for(Person person : listPerson) {
            System.out.println(person);
        }
    }
}

运行一下,大功告成:
file

程序使用Spring和MyBatis前后的对比

  1. MyBatis用于替换DAO.impl包下的实现类,也就是DAO实现类。替代方法是使用mybatis-config.xml和mapper.xml文件。
  2. Spring和MyBatis整合后,mybatis-config.xml文件也省略了,其中对应的内容被写进了Spring配置文件applicationContext.xml文件中。

第二个Spring程序的撰写,理解SpringAOP

搭建Spring开发环境

有关Spring开发环境的搭建,请参考:http://www.leonwish.com/archives/79

撰写第一个Spring程序,理解SpringIOC工厂机制

撰写第二个Spring程序前,需要首先理解SpringIOC机制,请参考:http://www.leonwish.com/archives/81

撰写第二个Spring程序

第一步:在Maven的pom.xml中添加AOP依赖,代码如下:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

第二步:确定目标类,编写核心功能(也可以理解为这是当前系统已经有的功能)
service包下新建UserService接口

package com.royotech.service;

public interface UserService {
    public boolean login(String username, String password);
}

service.impl子包下新建UserServiceImpl类,实现UserService接口。

package com.royotech.service.impl;

import com.royotech.service.UserService;

public class UserServiceImpl implements UserService{
    @Override
    public boolean login(String username, String password) {
        System.out.println("我是核心功能:我登陆成功了!我的名字:"+username+",我的密码:"+password);
        return true;
    }
}

第三步:编写新功能类。
在aop包下新建MyAdvice类,作为新功能。

package com.royotech.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAdvice implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("我是织入功能:开始统计啦!");
        invocation.proceed();//执行被切入类(目标类)中的既有方法的方法体。
        System.out.println("我是织入功能:统计结束啦!");
        return true;
    }

}

第四步:编写applicationContext.xml,配置目标类、新功能类、配置切入点

<?xml version="1.0" encoding="UTF-8"?>
<beans   xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 1. 配置目标类 -->
    <bean id="userServiceImpl" class="com.royotech.service.impl.UserServiceImpl"></bean>
    <!-- 2. 配置额外功能类 -->
    <bean id="myAdvice" class="com.royotech.aop.MyAdvice"></bean>
    <aop:config>
        <!-- 3. 确定切入点 --> 
        <aop:pointcut id="pcut" expression="execution(boolean com.royotech.service.impl.UserServiceImpl.login(java.lang.String,java.lang.String))"></aop:pointcut>
        <!-- 4. 将额外功能织入切入点 -->
        <aop:advisor advice-ref="myAdvice" pointcut-ref="pcut"/>  
    </aop:config>
</beans>

注意,xml头部需要添加aop相关内容。

第五步:大功告成,测试一下
在view包下新建PersonSpringAOP.java

package com.royotech.view;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.royotech.service.UserService;

public class PersonSpringAOP {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 
        //这里面用接口,不能用UserServiceImpl类
        //因为本质上讲动态代理自动生成的隐藏对象应该与目标类实现同样的接口
        //因此动态代理对象和目标类不是同类对象,只是继承了相同的方法。
        UserService userService = (UserService)ac.getBean("userServiceImpl");
        userService.login("ROYOTECH", "123123");
    }
}

运行一下,看看结果,欧耶!!!
file

理解为什么使用SpringAOP

AOP(Aspect Oriented Programming)面向切面编程。底层基于动态代理机制实现。简单的来说就是如果系统需要增加某额外功能的时候,在不改变原有代码的情况下,可以通过AOP机制将新的功能织入到程序的切入点(切入点可以精确到方法)上。这是非常好的一种解耦合的机制。作用类似于JAVA拦截器和过滤器。

我能想到的典型应用场景有两个:
客户之前委托第三方开发了某JAVA系统,现在委托给你做新功能添加。最稳妥的方式是以AOP的形式将新功能织入到现有系统中。这样不会影响之前的代码结构,后期也便于单独维护自己的代码。
假如我们想统计下当前所有Service层函数的执行时间,以便优化代码。不可能给每个函数单独增加统计时间的代码。最好的方法是通过AOP,将统计代码织入到函数切入点中。

实体类为什么要实现Serializable接口?

疑问

刚刚学习Java的时候,我们学习三层架构,三层架构中的一层就是持久化层,持久化层里面有实体类(Entity)、DAO接口、DAO接口实现类等概念。有关三层架构的理解,请参考:http://www.leonwish.com/archives/58
在我们建实体类的时候,往往都要实现Serializable接口,这是为什么呢?

回顾

在学习Java基础的时候,你是肯定接触过Serializable接口的。
一般都是在学习输入、输出流的时候,估计那个时候你也没太搞明白为什么要实现Serializable接口。

解释

Serializable直译过来就是“序列化”。估计听到这个解释就更懵!
经过研究,我将对象需要实现Serializable接口的原因总结如下:
A. Java对象跳出JVM就需要Serializable序列化。
所有在Java中创建的对象都是运行在JVM(Java虚拟机)中的,如果这个对象或者说这个对象的数据要跳出JVM,需要保存到数据库或者文件中的时候,这个对象就需要Serializable序列化。
B. Serializable序列化是JVM内环境和JVM外环境的翻译机。
在JVM内部,对象是以只有JVM能看懂的class文件形式存在的,而class文件在JVM外部是无法被解读的。比如我们随便用记事本打开一个class文件,看到的会是类似下面的这种乱码:
file
Serializable序列化的意思就是将对象以二进制的形式翻译一下,然后保存到JVM外部,因为二进制是计算机都能理解的语言。

总结

总结下,如果一个对象要跳出JVM保存,就需要进行Serializable序列化。
实体类作为和数据库打交道的对象,自然是需要将数据保存到JVM外的数据库上的,所以实体类实现Serializable接口就可以理解了。
但实际上,实体类实现Serializable接口是个约定俗成的事情,即使不继承,也不会影响实体类的运行,因为实体类和数据库打交道最终是通过拼接而成的SQL语句,而非直接将数据序列化传输给数据库。

第一个Spring程序的撰写,理解SpringIOC工厂机制

搭建Spring开发环境

有关Spring开发环境的搭建,请参考:http://www.leonwish.com/archives/79

撰写第一个Spring程序

第一步:在entity包下定义Person实体类。

package com.royotech.entity;

import java.io.Serializable;

public class Person implements Serializable{
    private Integer id;
    private String name;
    private String birthday;
    private String telephone;
    private String address;

    public Person() {
        super();
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", birthday=" + birthday + ", telephone=" + telephone
                + ", address=" + address + "]";
    }
}

备注:

  1. 实体类的创建可以通过Eclipse自动生成代码的方式快速完成。
  2. 实体类为什么要实现Serializable接口,请参考文章:http://www.leonwish.com/archives/83

第二步:在applicationContext.xml文件下的<beans>标签下增加以下<bean>标签,内容如下:

<bean id="person" class="com.royotech.entity.Person">
    <property name="id" value="1"></property>
    <property name="name" value="Leon"></property>
    <property name="birthday" value="1990-01-01"></property>
    <property name="telephone" value="13811811118"></property>
    <property name="address" value="北京市西城区"></property>
</bean>   

添加<bean>标签的意思就是希望项目中的某一个类交由Spring框架去管理,由Spring工厂创建对象。
<bean>标签的id属性:对象创建好后,通过这个id取出来使用。
<bean>标签的class属性:交给Spring工厂创建对象的全类名。
<bean>标签的下的<property>标签:类的属性。

**第三步:在view包下创建PersonSpringIOC类

package com.royotech.view;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.royotech.entity.Person;

public class PersonSpringIOC {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 
        Person p = (Person)ac.getBean("person");  
        System.out.println(p);
    }
}

运行,输出结果如下:
file

理解为什么使用SpringIOC工厂机制创建对象

不得不说,从这个案例来看,创建一个类变得如此复杂,纯属吃饱了撑的,但是我们换个角度去想:

  • 使用SpringIOC创建对象类似于用乐高建房子,房子建好后拆卸仍然很容易。
  • 而使用传统方法创建对象类似用积木和胶水建房子,房子建好了,想拆开可是非常困难的。