以下是学习JavaWeb相关笔记,含有Struts2和hibernate相关内容,有的是学习的教材,但是内容较老,在机器上死活跑不起来,在CSDN,百度上也找了不少解决方法,有的解决了,有的到现在也不知道为啥,出现了各种各样的问题。在GitHub上查过一些项目,看过官网的示例文档,最后总归Struts2和Hibernate都能动了。
尤其是Struts2时,明明一个相同的项目,导入人家的能运行,我原封不动写的就不行。也正是因为这,用的IDE是eclipse,什么Jar包啊,project facet啊,Tomcat啊,什么编译环境啊,Java版本啊,都搞了一遍,甚至还因为这个学了Maven。
都说Struts2是老技术了,但这此学习经历也让我发现了许多其他问题,学到了不少其他方面的技术。目前学习了Spring,感觉就不像学习前面那么费劲了,在向前学习实践的过程中,之前出现的不解的问题好像就有了答案。
以下笔记。
<%--下面的符号是换行标--%>
</br>
下面的表达式,不能有分号
<%=count++%>
连接数据库:
<%@page import="java.sql.*" %> <!--@号不能忘记,JSP文件头加入如下语句导入包,如SQL的-->
<!--以下为具体连接数据库语句参考-->
<%Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/qq?characterEncoding=utf8&serverTimezone=GMT","root","c534zstc");
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from qq.friend");
%>
javabean 要有构造方法
<form id="form1" method="post" action="request1.jsp">
Struts2
配置struts
1.填加Jar包到lib,全选填加build path;
2.在web.xml里加filter:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!--上面一长串要去下的struts包里核对,可能文件结构发生变化-->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.src里新建struts.xml:
<struts>
<constant name="struts.devMode" value="true" />
<!--下面两行是后加的国际化资源文件-->
<constant name="struts.custom.i18n.resources" value="mess"/>
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<package name="basicstruts2" extends="struts-default">
<!--这个地方加action等-->
</package>
</struts>
4.上面所谓国际资源文件,对应为mess. Properties.
war中的JSP能运行,我自己写的却不可以。。
1.eclipse JAVA struts tomcat 等全升到最新。。。
2.右键工程,properties里面的java build path ,Modulepath和Classpath要区分开,在Classpath中ADD JAR是加入本工程内已经拷入的jar包,tomcat加到classpath里
3.Project facets 里面选好Dynamic web Module、Java、JavaScript及版本号,其中Dynamic web Module的号要和web.xml上的对应上,web.xml不同号,开头不同
4.Project Reference里面点选相关工程。(好像不选也行)
5.**终极解决:**META-INF里面的manifest.mf文件极其重要,不知道原理,总之maven好的其他war文件后,用里面相同的文件就解决找不到index.jsp文件的问题了。(这个问题困了将近3天,查了好多,最后最后发现了)
6.下载Java要到oracle官网去下,直接搜出来的不对劲,这里用的是jdk14。
7.其实以上都不一定好使。。尤其第5条,之前是这样的,改了就好,再试又不行了。目前最稳的方式是直接maven官网上的example,然后在eclipse里导入maven好的war,然后自己再改成想要的。
通配符
<action name="*Action" class="org.crazyit.app.Action.{1}Action">
这个{1}代表进行模板匹配时的第一个*所代替的字符串
${属性值}.jps : 这个属性值是Action类里面的一个private 参数 XXX.属性值
PreResultListener:
他可在Action完成控制处理后、系统转入实际的物理视图 之间 被回调。用法如下:(在execute等方法里写)
public class LoginRegistAction
extends ActionSupport{
...
public String execute() throws Exception
{
ActionInvocation invocation = ActionContext
.getContext().getActionInvocation();
invocation.addPreResultListener(new PreResultListener()
{
public void beforeResult(ActionInvocation invocation,
String resultCode)
{
// 具体方法,也可加入日志等
}
});
if (){
return SUCCESS;
}
return ERROR;
}
}
Convention插件
约定优于配置:
Hibernate 5.4
使用的数据库类型:
MySQl(InnoDB),选dialect时候加个5,如
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
数据库驱动:
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
URL:
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/qq?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false</property>
jdbc:mysql://localhost:3306/qq?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
其中qq代表服务器名,?serverTimezone=UTC 为时区,GMT%2B8为东8区,&后面再加useUnicode=true&characterEncoding=UTF-8 解决中文乱码问题
XML中的&是读不出的,后面加 amp;
mapping resources
hibernate.cfg.xml里面的mapping resources 里面选Resource的路径,不选class
<mapping resource="org/hibernate/dm/QQ.hbm.xml"/>
hibernate.cfg.xml 要有以下三项内容:
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
是否显示SQL,是否按格式显示,更新方式update
Could not bind factory to JNDI问题:
使用hibernate时,将hibernate.cfg.xml中 的那么属性去掉即可。因为,有了name属性hibernate会试图把这个sessionfacotry注册到jndi中去。
closing inbound before receiving peer’s close_notify 问题
修改一下链接的url配置信息加上useSSL=false
url=jdbc:mysql://192.168.0.148:3306/test1?useSSL=false 加的时候注意后面的&的处理方式
访问小样代码:
SessionFactory sessionFactory=null;
Configuration configuration=new Configuration().configure();
ServiceRegistry erviceRegistry=configuration.getStandardServiceRegistryBuilder().build();
//创建sessionFactory
sessionFactory=new etadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
//创建session
Session session=sessionFactory.openSession();
//创建transaction
Transaction transaction=session.beginTransaction();
//按对象方式存入
QQ qq=new QQ("asdg","asdgasg","asdgasg");
session.save(qq);
//启动
transaction.commit();
//先关session,再sessionfactory
session.close();
sessionFactory.close();
Session缓存
flush()方法是强制让数据库与缓存中的对象保持一致,首先判断是否一致,不一致再发SQL语句
refresh(XXX)方法是强制让缓存中的对象与数据库中保持一致,都会发出SQL语句。
session里不允许有两个ID值相同的对象
get and load:
system.out.println(student)就是使用
C3P0数据库连接池:
减少访问压力
日期时间对象的方法:
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date birthday=sdf.parse("1998-11-22");
映射关系的基本配置
派生字段,带SQL语言的,用“()”括起来,这个字段没有COLUMN,在实际表里没有。
这个配置中length长度是显示长度,不是大小 大小是数据类型决定的。
多对一属性
写在“多”的那个属性配置文件里,同时POJO里面要加入“一”的那个表的外键
先增加一的一端发起的SQL语句少,先增加多的一端发起的SQL语句多!!
双向多对一属性
一的一端的POJO里加入多的一端的外键的集合,如下
Private Set<student> students=new HashSet<>();
一端使用的不是many-to-one,使用的是set
双向的,在一的那一端加入inverse=“true”属性!减少冗余UPDATE语句
cascade属性:级联,=DELETE的话,要删一块删了,一般不用
一对一属性
many-to-one中加入unique属性,另一个还是one-to-one 也还是变成一对一的关系
多对多
通常加入一个中间表,把关联的都写进去,形成一对多 然后多对一。
双向的关系,互相都要加一下。如下图上面还有个Set courses=new HashSet<>()。。等几行同下面的前三行。
且只能有一个表的键去维护关系(inverse=true属性)
组件映射
没有ID属性,如学生的地址、生日、班级等
Public class Student{ //POJO
private int id;
private String name;
private StudentInfo studentInfo; //实地组件
}
组件配置写法:
<component name="studentInfo" class="StudentInfo"> //组件属性 、 类名
<property name="address" type="string">
<column name="address"/>
</property>
<property name="birthday" type="date">
<column name="birthday"/>
</property>
<property name="classes" type="string">
<column name="classes"/>
</property>
</component>
继承映射
Animal , Bird Pig 类分别继承Animal 这时配置文件写在Animal里面。
<class name="cn.hasd.hdemo.entity.Animal" table="ANIMAL" discrimination-value="animal">
<!--上面也要有辨别字段-->
<id name="id" type="int">
<column name="ID"/>
<generator class="native">
</id>
<!--辨别字段,放在ID字段之后-->
<discriminator column="type" type="string"></discriminator>
<property name="name" type="java.lang.String">
<column name="NAME"/>
</property>
....<!--配置自己属性-->
<subclass name="cn.hasd.hdemo.entity.pig" discriminator-value="pig">
<property name="weight"/>
</subclass>
...
ANMINAL一个表,如下
<generator class="uuid2"/><!--主键生成策略为uuid2时,ID属性为string-->
<union-subclass ...></union-subclass><!--不需要key-->
uuid2:使用JDK自动生成的ID,32位
延迟加载:
如果用他的一个属性就使用立即加载get,如果访问他的一个程序,即用延迟加载(懒加载)load
使用原生SQL语句查询
Query<Object[]> query=session.createNativeQuery("select * from teacher as t where t.name like ? and t.id=?");
query.setParameter(1,"%y%").setParameter(2,1) ;//?占位符从1到2 原生SQL
List<Object[]> result=query.list();