一、JSP与Servlet
1、 基础语法
1.1声明 <%! int i = 0; %>
1.2表达式 <%= i %>
1.3脚本段 <% sth %>
1.4 Page指令用于定义JSP文件中的全局属性 <%@page [language=”java”][import=””]%>
1.5 include指令用于在JSP中包含一个静态文件,同时解析这个JSP文件中的JSP语句。 文件名一般是相对路径
1.6 Taglib定义一个标签库以及其自定义标签的前缀
<%@ taglib uri=”http://www.baidu.com” prefix=”public %>
<% %>
1.7 八个动作指令
页面跳转
包含页面
创建Bean
设置Bean属性jsp:setProperty
获得Bean属性
使用Applet插件
Unable to loadapplet
插件定义参数
插件错误提示
1.8内置对象
Request 请求对象
Response 响应对象
Session 会话对象
Application应用程序对象
Out 输出对象
Config 配置对象
Page 页面对象
PageContext 页面上下文对象
Exception 例外对象
1.9 JDBC访问数据库
Connection conn = DriverManager.getConnection(“jdbc:mysql:datasource”,“usr” “pwd”);
Statement stmt = conn.creatStatement();
ResultSet rs = stmt.executeQuery(“SELECT aFROM table1”);
While (rs.next()) …
用完及时关闭
2、 创建JSP页面
1.1第一行是JSP固定设置语句
1.2通过request对象取得当前上下文路径的Path,并通过request对象取得协议、主机名、端口,将这四个变量组合起来形成一个URL的路径。
1.3设置HTML的head信息,将取得的URL路径设置到
<%@ pagelanguage=”java” import=”java.util.*” pageEncoding=”UTF-8” %>
<%
String path =request.getContextPath();
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
3、mysql语句大全
创建数据库 CREATE DATABASE test
删除数据库 DROP DATABASE test
进入数据库 USE TEST
创建新表 create table table1(col1 type1[not null][primary key],col2 type2 [not null]);
插入 insert into table1(f1,f2) values(value1,value2);
4、JavaBean
4.1使用DBAccess和UserBean来处理数据库
public class DBAccess {
private String drv = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/test";
private String usr = "root";
private String pwd = "12345";
//数据连接对象
private Connection conn = null;
//数据库声明对象
private Statement stm = null;
//数据库结果集对象
private ResultSet rs = null;
public boolean createConn() {
boolean b = false;
try {
Class.forName(drv).newInstance();
conn =DriverManager.getConnection(url, usr, pwd);
b = true;
} catch(SQLException e) {
} catch(InstantiationException e) {
} catch(IllegalAccessException e) {
} catch(ClassNotFoundException e) {
}
return b;
}
public boolean update(String sql) {
boolean b = false;
try {
stm = conn.createStatement();
stm.execute(sql);
b = true;
} catch(Exception e) {
}
return b;
}
public void query(String sql) {
try {
stm = conn.createStatement();
rs = stm.executeQuery(sql);
} catch(Exception e) {
}
}
/*移动操作*/
public boolean next() {
boolean b = false;
try {
if (rs.next())b = true;
} catch(Exceptione) {
}
return b;
}
/*移动到目标行后取值*/
public String getValue(String field) {
String value = null;
try {
if (rs != null) value = rs.getString(field);
} catch(Exception e) {
}
return value;
}
public void closeRs() {
try {
if (rs != null) {
rs.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
}
public void closeStm() {
try {
if (stm != null) {
stm.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
}
public void closeConn() {
try {
if (conn != null) {
conn.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
}
(set,get…)
}
4.2开发javabean业务逻辑组件UserBean
public class UserBean {
public boolean isValid(String username, String password) {
boolean isValid =false;
DBAccess db = newDBAccess();
if(db.createConn()) {
String sql = "select * from user whereusername='" + username + "' and password='" + password + "'";
db.query(sql);
if(db.next()){
isValid = true;
}
db.closeConn();
db.closeRs();
db.closeStm();
}
return isValid;
}
public boolean isExist(String username) {
boolean isExist =false;
DBAccess db = newDBAccess();
if(db.createConn()) {
String sql = "select * from user whereusername='" + username + "'";
db.query(sql);
if(db.next()) {
isExist = true;
}
db.closeConn();
db.closeRs();
db.closeStm();
}
return isExist;
}
public void add(String username, String password) {
DBAccess db = newDBAccess();
if(db.createConn()) {
String sql = "insert into user(username,password)values ('" + username + "','" + password + "')";
db.update(sql);
db.closeConn();
db.closeRs();
db.closeStm();
}
}
}
5、Servlet
action=”login.action.jsp” 可替换为 acton=”UserServlet.do?method=login”
二、Hibernate
6、关于Hibernate
配置文件,在src下添加hibernate.cfg.xml
xml version="1.0"encoding="UTF-8"?>
DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="myeclipse.connection.profile">JDBC for MySQLproperty>
<property name="connection.url">jdbc:mysql://localhost:3306/demoproperty>
<property name="connection.username">rootproperty>
<property name="connection.password">12345property>
<property name="connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="dialect">org.hibernate.dialect.MySQLDialectproperty>
<mapping resource="com/demo/hibernate/beans/User.hbm.xml"/>
session-factory>
hibernate-configuration>
映射文件,负责持久化类与数据库表之间的映射,其根元素为hibernate-mapping,并通过属性package指定类所在的包。每一个表使用一个class定义,name属性表表示;类的名称,table表示关联的表名,通过property子元素来映射类的变量名与数据库表字段名之间的映射关系。
1.根元素
schema和catalog属性,指明了这个映射所连接的表所在的shema和/或catalog名称。
auto-import属性默认让我们在查询语言中可以使用非全限定名的类名。假设有两个持久化类,它们的非全限定名一样(类名一样,在不同包里),则应该设置auto-import=false,否则会抛出异常。
2.
mutable=”false”,则不可以被应用程序更新或删除
3.
若是联合主键
4.
assigned-主键由外部程序负责生成
hilo-使用hi/lo高/低位算法高效地生成long、short、int类型的标识符
seqhilo-与hilo类似,只是主键历史状态保存在Sequence中,适用于如Oracle
increment-标识主键按数值顺序递增。同一数据库有多个实例访问时,此方法必须避免使用。
identity-采用数据库提供的主键生成机制
sequence-采用数据库提供的sequence机制生成主键
native-根据底层数据库自行判断采用identity、hilo、sequence中的一种
uuid.hex、uuid.string、foregin
select-通过数据库触发器选择一些唯一主键的行为并返回主键值来分配一个主键
5.
6.
必须确保PERSON和EMPLOYEE中相关的字段是相等的
。。。
6.
这个表的一个外键引用目标表的主键字段
在com.demo.hibernate.beans包添加User.hbm.xml
xml version="1.0"encoding="UTF-8"?>
DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.demo.hibernate.beans">
<class name="User" table="user">
<id name="id"column="ID" type="integer">
<generator class="native"/>
id>
<property name="username"column="username" type="string"/>
<property name="password"column="password" type="string"/>
class>
hibernate-mapping>
编写持久化类User.java,一张数据库表对应一个持久化类,通过getter和setter方法访问属性。
package com.demo.hibernate.beans;
public class User {
private java.lang.Integer id;
private java.lang.String username;
private java.lang.String password;
(get,set…)
}
辅助类HibernateSessionFactory.javaHibernate的Session,是一个持久化管理器,通过它从数据库中存取User。
首先从sessioinFactory中获取一个Session
这个类不但在它的静态初始器中使用了SessionFactory,还使用了一个ThreadLocal变量来保存Session作为当前工作线程。ThreadLocal?
packagecom.demo.hibernate.util;
importorg.hibernate.*;
importorg.hibernate.cfg.Configuration;
public classHibernateSessionFactory {
private static StringCONFIG_FILE_LOCALTION ="/hibernate.cfg.xml";
private static final ThreadLocalthreadLocal = new ThreadLocal();
private static final Configurationcfg = new Configuration();
private static org.hibernate.SessionFactorysessionFactory;
//取得session
public static SessioncurrentSession() throws HibernateException {
Session session =(Session) threadLocal.get();
if (session == null){
if(sessionFactory == null) {
try{
cfg.configure(CONFIG_FILE_LOCALTION);
sessionFactory= cfg.buildSessionFactory();
}catch (Exception e) {
System.err.println("%%%%Erro Create SessionFactory %%%%");
e.printStackTrace();
}
}
session= sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
//关闭session对象
public static void closeSession()throws HibernateException {
Session session =(Session)threadLocal.get();
threadLocal.set(null);
if (session != null){
session.close();
}
}
}
DAO(数据访问接口)类,DAO层只负责调用Hibernate API实现CRUD操作,Service层面向用户负责调用DAO层的代码。
以下实现一个getUser()函数,根据用户名查询一个对象,通过session执行事务、创建查询对象、返回查询的数据对象。操作session的代码都是Hibernate提供的API。
packagecom.demo.hibernate.dao;
import ..;
public classUserDAO {
public User getUser(Stringusername) throws HibernateException {
Session session =null;
Transaction tx =null;
User user = null;
try {
session= HibernateSessionFactory.currentSession();
tx =session.beginTransaction();
Queryquery = session.createQuery("from User where username=?");
query.setString(0,username.trim());
user =(User) query.uniqueResult();
query= null;
tx.commit();
} catch(HibernateException e) {
throwe;
} finally {
if (tx!= null) {
tx.rollback();
}
HibernateSessionFactory.closeSession();
}
return user;
}
}
Service类,Service层即服务层,也就是面向用户服务,定义的方法都是与实际的业务相关的,可调用DAO层。
以下有一个函数valid(),根据用户名和密码来判断用户是否存在。然后编写一个main()入口函数,调用valid()函数执行业务的调用。
package com.demo.hibernate.service;
public class UserService {
public boolean valid(String username, String password) {
UserDAO test = new UserDAO();
User user = test.getUser("root");
if (user.getPassword().equals(password)) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
UserService service = new UserService();
boolean login = service.valid("root", "12345");
System.out.print("验证结果为:" + login);
}
}
7、Hibernate接口
1.Configuration装载配置
Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃了。
1.1为Configuration指定映射文件
直接实例化Configuration来获取一个实例,并为它指定XML映射定义文件。如果映射定义文件在类路径(classpath)中,则使用addResource()
Configuration cfg = new Configuration().addResource(“com/demo/hibernate/beans/User.hbm.xml”);
1.2为Configuration指定持久化类
指定被映射的类,让Hibernate寻找映射定义文件
Configuration cfg = newConfiguration().addClass(com.demo.hibernate.beans.User.class);
1.3为Configuration指定配置属性
Configuration cfg = new Configuration().addClass(com.demo.hibernate.beans.User.class)
.setProperty(“hibernate.dialect”, “org.hibernate.dialect.MySQLInnoDBDialect”)
.setProperty(“hibernate.connection.datasource”, “java:comp/env/jdbc/test”);
1.4Configuration三种加载方法
使用Hibernate.cfg.xml
Configuration cfg = new Configuration();
cfg.configuration(“hibernate.cfg.xml”);
使用Hibernate.properties 需要通过硬编码的方式指定映射文件或POJO类,Hibernate会自动找到另一方
Configuration cfg = new Configuration();
cfg.configuration(“/hibernate.propertiesl”);
cfg. addClass(com.demo.hibernate.beans.User.class); //或者addResource()
完全在构造是进行硬编码设置
Configuration cfg = newConfiguration().addClass(com.demo.hibernate.beans.User.class)
.setProperty(“hibernate.dialect”, “org.hibernate.dialect.MySQLInnoDBDialect”)
.setProperty(“hibernate.connection.datasource”, “java:comp/env/jdbc/test”)
.setProperty(“hibernate.order_updates”, “true”);
2.使用SessionFactory创建Session
SessionFactory在Hibernate中实际起到了一个缓冲区的作用
SessionFactory sessionFactory =cfg.buildSessionFactory();
一个项目通常只需要一个SessionFactory就够了。为当前用户的访问定义一个本地线程变量:
Private static final ThreadLocal threadLocal = new ThreadLocal();
该线程变量是静态的,对每一个访问该线程的用户产生一个实例。在要取得Session对象时,首先从当前用户的线程中取得Session对象,若还没有创建,则再去创建。
Session session = (Session) threadLocal.get();
if (session == null) {
if (sessionFactory == null) {
try {
cfg.configure(CONFIG_FILE_LOCALTION);
sessionFactory = cfg.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}
ThreadLocal是用于在并发环境下避免竞争、简化编程的机制,它在并发环境下提供了一个逻辑上全局的访问点,来访问线程本地对象。它为每一个使用使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立第改变自己的副本,而不会和其他线程的副本冲突。从=线程角度看,就好像每一个线程都完全拥有该变量。
3.使用Session操纵数据库 所有操作都要放在事务中
3.1使用save()保存对象
save()用于将一个新实例化的对象持久化,保存到数据库中。
session = HibernateSessionFactory.currentSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setId(5);
user.setUsername("test");
user.setPassword("12345");
session.save(user);
tx.commit();
System.out.println(user.getUsername());
3.2使用load()装载对象
当知道某个实例的持久化标识(如 1),就可以使用Session的load()方法来获取它。此外,还可以覆盖掉该实例原来的数据。
session = HibernateSessionFactory.currentSession();
User user = new User();
user.setUsername("oldname");
session.load(user, new Integer("1"));
System.out.println(user.getUsername());
3.3使用get()装载对象
当不确定是否有匹配的行记录存在,应该使用get()方法,它会立刻访问数据库,如果没有对用的行,则返回null。
session = HibernateSessionFactory.currentSession();
User user = (User) session.get(User.class, new Integer("4"));
if (user == null) {
user = new User();
user.setUsername("Alice");
user.setPassword("12345");
session.save(user);
}
System.out.println(user.getUsername());
3.4使用flush()强制提交刷新
当一个实例被更改,可以使用flush()将更改后的实例对象强制保存到数据库中
session = HibernateSessionFactory.currentSession();
User user = (User) session.get(User.class, new Integer("1"));
user.setUsername("updateRoot");
session.flush();
System.out.println(user.getUsername());
3.5使用update()提交游离状态的对象
update()用于根据给定的detached(游离状态)对象实例的标识更新对应的持久化实例
3.6使用delete()移除持久化对象
该函数用于从数据库中删除对象对应的记录
以下先使用get()加载标识符为4的实例对象,然后删除该对象,并强制执行刷新。
session = HibernateSessionFactory.currentSession();
User user = (User) session.get(User.class, new Integer("2"));
session.delete(user);
session.flush();
System.out.println(user.getUsername());
3.7使用refresh()强制装载对象
任何时候都可以使用refresh()方法强迫装载对象和它的集合。
4.使用Transaction管理事务
Transaction接口是对实际事务实现的一个抽象,是为了让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。
一个典型的事务:在创建完Session对象后即使用beginTransaction()启用事务,从此开始直到commit()之间的代码,都会处于同一个事务中。这两个函数之间的所有的数据库代码都会在commit()时一次性提交,在提交时,如果某一句代码执行出现异常,就会回滚这一次事务之间的所有执行代码。
public User getUser(String username) throws HibernateException{
Session session = null;
Transaction tx = null;
User user = null;
try {
session = HibernateSessionFactory.currentSession();
tx = session.beginTransaction();
Query query = session.createQuery("from User where username=?");
query.setString(0, username.trim());
user = (User) query.uniqueResult();
query = null;
tx.commit();
} catch (HibernateException e) {
throw e;
} finally {
if (tx != null) {
tx.rollback();
}
HibernateSessionFactory.closeSession();
}
return user;
}
Tips:如果Session抛出了异常,事务必须回滚,Session也会被废弃。在异常发生后,Session的内部状态可能会与数据库失去同步。
5.使用Query进行HQL语句查询
Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
要取得Query对象,需要使用Session的creareQuery()函数来执行查询。其查询的对象是Hebernate的持久化对象名,Hibernate会根据该对象名找到要查找的表名。
5.1不带参数的查询
当不确定是否有匹配的行记录存在,应该使用get()方法,它会立刻访问数据库,如果没有对用的行,则返回null。
Query query = session.createQuery(“from User”);
5.2带参数的查询
接口Query提供了对命名参数、JDBC风格的问号(?)参数两种参数绑定方法。
命名参数在查询字符串中是形如:name的标示符。命名参数的优点是:
命名参数与其在查询串中出现的顺序无关;
它们可在统一查询串中多次出现;
它们本身是自我说明的。
Query query =session.createQuery("from User whereusername=:username");
query.setString("username", "root");
也可以是集合型参数。
List names = new ArrayList();
names.add("root");
names.add("alex");
Query query =session.createQuery("from User whereusername in (:nameList)");
query.setParameterList("nameList", names);
Query使用问号参数时与JDBC不同,Hibernate对参数从0开始计数。
Query query =session.createQuery("from User whereusername=?");
query.setString(0, "root");
5.3取得List结果集
以上只是取得了一个Query查询的对象,一个查询通常在调用List()时被执行,执行结果会完全装载进内存中的一个集合。
List list = query.list();
5.4取得迭代列表结果集
某些情况下,使用iterate()可以得到更好的性能。Iterate()比list()慢。
有两种方法可以取得迭代结果集,一种是使用Query的iterat()方法,另一种是使用list()后再执行iterator()方法。第二种方法的效率比第一种高。
Iterator it1 = query.iterate();
Iterator it2 =query.list().iterator();
while (it2.hasNext()) {
User user = (User) it2.next();
}
5.5取得一个对象
当知道当前查询只会返回一个对象,则可使用list()的快捷方式uniqueResult()来取得一个对象。
比如,现在我们知道数据库中Username是唯一的:
Query query =session.createQuery("from User whereusername=?");
query.setString(0, "root");
user = (User) query.uniqueResult();
5.6标量查询
查询可以在select从句中指定类的属性,甚至可以调用SQL统计函数。属性或统计结果被认定为“标量(Scalar)“的结果(而不是持久的实体)。
以下使用count()计数函数来取得一个标量结果
Iterator result =session.createQuery(
"selectuser.username,count(user.password) from User user " +
"group by user.username").list().iterator();
5.7分页查询
需要指定结果集的范围(希望返回的最大行数/或考试的行数)时
以下通过setFirstResult()来设置起始位置,通过setMaxResultd()来设置结束位置
Query query = session.createQuery("from User");
query.setFirstResult(10);
query.setMaxResults(20);
List list = query.list();
5.8创建SQL查询
可以使用createAQLQuery()方法,用普通的SQL来描述查询,并由Hibernate处理将结果集转换成对象的工作。Hibernate3允许使用手写的SQL来完成所有的create、update、delete、和load操作。其中的SQL别名需要大括号包围起来。
List users = session.createSQLQuery("SELECT{user.*} FROM User {user}").list();
6.使用Criteria进行条件查询
6.1创建Criteria实例
与Query的方法类似,不同的是其参数是持久化类的名称。
Criteria criteria = session.createCriteria(User.class);
criteria.setMaxResults(50);
List users = criteria.list();
6.2添加查询条件
查询条件是通过org.hibernate.Criteria.Restrictions类来实现的,用来模拟SQL语句中的条件关键字,例如like、between、and、or等。通过调用add()来添加多个Restrictions实例。
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like("username", "root%"));
criteria.add(Restrictions.between("ID", 1, 10));
List users = criteria.list();
6.3添加排序条件
可以使用org.hibernate.Criteria.Order来为查询结果排序,它共包含两个方法,asc()和desc(),分别实现SQL语句中的asc和desc关键字。
List users = session.createCriteria(User.class)
.add(Restrictions.like("username", "root%"))
.addOrder(Order.asc("username"))
.addOrder(Order.asc("password"))
.setMaxResults(50).list();
6.4使用实例查询
可以使用org.hibernate.Criteria.Example类允许通过一个给定实例来创建一个条件查询
User user = new User();
user.setUsername("root");
List results = session.createCriteria(User.class)
.add(Example.create(user))
.list();
三、Struts
1、MVC模式
|
||
|
||
|
|
|
(蓝色箭头为方法调用,绿色箭头为事件)
Struts体系结构实现MVC设计模式:Controller负责控制流程,由ActionServlet负责读取struts-config.xml,并使用ActionMapping来查找对应的Action;Model由系统状态Bean ActionForm和商业逻辑的JavaBean来构建;View是由JSP和Struts提供的自定义标签来实现。
2、Structs核心组件
类 |
描述(对应的MVC组件的职责) |
ActionServlet |
控制器,接受用户请求和状态改变,以及发出视图选择 |
ActionMapping |
状态改变事件 |
Action |
控制器的一部分,用于模型交互,执行状态或状态查询,以及告诉ActionServlet下一个选择的视图 |
ActionForward |
用户指向或者视图选择 |
ActionForm |
状态改变的数据 |
Tips:每个Action都只建立一个instance。Action不是线程安全的。不要在Action中包含任何业务逻辑操作,而是应该调用一个Model层的JavaBean来实现业务逻辑操作。
3、Structs的六个类 需要开发的类只有Action和ActionForm Bean
3.1 ActionServlet
是Struts的核心控制器,一个系统中只需要一个。可以通过继承该类来扩展一个新的Servlet,但通常直接使用默认的ActionServlet,只需要在web.xml中配置ActionServlet的相关属性即可。
3.2 ActionMapping
是struts-config.xml中配置元素的实例对象,该类与struts-config.xml中的元素和属性相匹配。该类是一个通用类,不需要开发人员开发。
3.3 RequestProcessor
是ActionServlet的代理处理类,与ActionServlet相似,通常使用默认类即可。若要扩展新的功能,只需要实现一个继承该类的新的处理类即可。
3.4 Action
是struts-config.xml中
Structs提供了多种Action供选择使用。普通的Action只能通过调用execute执行一项任务,而DispatchAction可以根据配齐参数执行,而不是仅进入execute()函数,这样可以执行多种任务,如insert、update等。LookupDispatchAction可以根据提交表单按钮的名称来执行函数。
3.5 ActionForm Bean
是struts-conig.xml中配置的
3.6 ActionForward
用于根据struts-conig.xml中action的配置进行页面转发,是一个通用类,不需要开发。
4、Structs开发流程
首先添加structs 1.2
4.1 编写输入表单
Input.jsp中添加一个表单,表单元素