SSH初体验系列--Hibernate--2--crud操作
Ok,今天比较详细的学习一下hibernate的C(create)、R(read)、U(update)、D(delete) 相关api...
前言
Session: 是Hibernate持久化操作的基础,提供了众多的数据库操作方法,如save(),update(),delete()。。。etc,用于完成对象的增加,修改,删除等方法.
后面代码中使用到的HinernateUtil类:是用于构建SessionFactory(Hibernate提供的获取session的工厂类)的一个封装类,在前面的文章SSH初体验系列--Hibernate--1--环境配置及demo中有详细代码,可自行查看.
一) 增(C)
1.添加单条个数据;
@org.junit.Test
public void save(){
//创建对象
Feedback newItem=new Feedback();
newItem.setUsername("andew17");
newItem.setContent("测试单条插入");
newItem.setSendTime(new Timestamp(System.currentTimeMillis())); Session session=null;
Transaction tx=null;
try{
//获取session对象
session= HibernateUtil.openSession();
//开启事务
tx=session.beginTransaction();
//执行保存
session.save(newItem);
//提交事务
tx.commit();
}catch(Exception e){
//异常时,事务回滚
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}
添加单条数据
2.批量添加数据;
可以通过for循环,将数据统一添加到一级缓存session中,再commit到数据库;
@org.junit.Test
public void saveMany(){
//创建对象
List<Feedback> feedbackList=new ArrayList<>();
for(int i=0;i<10;i++){
Feedback newItem=new Feedback();
newItem.setUsername("andew"+i);
newItem.setContent("测试单条插入"+i);
newItem.setSendTime(new Timestamp(System.currentTimeMillis()));
feedbackList.add(newItem);
}
Session session=null;
Transaction tx=null;
try{
//获取session对象
session= HibernateUtil.openSession();
//开启事务
tx=session.beginTransaction();
//执行保存,此时只是保存到Session缓存中,并没有同步到数据库
Feedback feedback=null;
for(int i=0;i<feedbackList.size();i++){
feedback=feedbackList.get(i);
session.save(feedback);
}
//提交事务,就缓存同步到数据库
tx.commit();
}catch(Exception e){
//异常时,事务回滚
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}
for循环执行session的save方法
如果数据量不大时,或者对性能没有极致的追求时,这种方法还ok;但是当批量插入数据量较大时,这个方式的弊端就体现出来了.
弊端主要有两点:a,循环向Session添加,修改数据时,Session对象自身开辟的一级缓存会不断被消耗,直到耗尽(outOfMemoryError);
b,通过在hibernate.cfg.xml文件配置"显示sql语句"
<!--显示SQL语句-->
<property name="show_sql">true</property>
再跟踪打印的SQl语句,很容易就发现,内部其实还是执行了n(n=数据量)次的插入操作,而不是一次语句执行,在性能上,可想并不是很好. 对于喜欢追求代码性能的小伙伴,这是让人难以忍受的,如鲠在喉...
Hibernate: select max(id) from feedback
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Disconnected from the target VM, address: '127.0.0.1:59399', transport: 'socket' Process finished with exit code 0
解决方案:a,对于内存溢出,可以在代码中进行判断,每隔n条,释放一次缓存;并且在hibernate.xfg.xml中配置每次提交sql的数量
<property name="hibernate.jdbc.batch_size">10</property>
// 每处理20条清空缓存
session.save(newItem);
if (i%20 == 0) {
session.flush();
session.clear();
}
b.若想在性能上有所提升,可以绕过Hibernate Api,直接使用jdbc api来做批量插入;
@org.junit.Test
public void saveJdbc(){
//创建对象
List<Feedback> feedbackList=new ArrayList<>();
for(int i=0;i<;i++){
Feedback newItem=new Feedback();
newItem.setUsername("andew"+i);
newItem.setContent("测试单条插入"+i);
newItem.setSendTime(new Timestamp(System.currentTimeMillis()));
feedbackList.add(newItem);
}
String insertSql="insert into feedback (username, content, sendTime) values (?, ?, ?)"; Session session=null;
// Transaction tx=null;
try{
session= HibernateUtil.openSession();
//tx=session.beginTransaction();
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//这里面就得到connection了
PreparedStatement stmt=connection.prepareStatement(insertSql);
//方式1:自动提交
/*connection.setAutoCommit(true);
for(int i=0;i<feedbackList.size();i++){
stmt.setString(1,"andrew"+1);
stmt.setString(2,"test content "+i);
stmt.setTimestamp(3,new Timestamp(System.currentTimeMillis()));
stmt.execute();//此语句,每次执行,都会将一条数据插入到db
}*/ //方式2:批量提交
connection.setAutoCommit(false);
for(int i = 0; i<feedbackList.size();i++) {
stmt.setString(1,"andrew"+1);
stmt.setString(2,"test content "+i);
stmt.setTimestamp(3,new Timestamp(System.currentTimeMillis()));
stmt.addBatch();
if (i % 10 == 0) {
stmt.executeBatch();
connection.commit();//此处执行一次db插入操作
}
}
stmt.executeBatch();
connection.commit();
}
});
////注意:此时不能再用事务,会报错:org.hibernate.TransactionException: Unable to commit against JDBC Connection
// tx.commit();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}
jdbc批量插入数据
其中有几个地方需要注意:
a,connection对象的获取:
a)过时方式:session.connection();
但是这个方法Hibernate不推荐使用,The method connection() from the type Session is deprecated
在3.3以后的版本中已经被废除了。 b)Session.doWork;
3.3官方的替代方法是用Session.doWork(Work work);
传入的参数work是一个接口,可以:
HibernateFactory.getSession().doWork(
new Work() {
public void execute(Connection connection) {
// 这里面就得到connection了,
}
}
);
b.代码中的"方式2,批量提交",就是我们最终想要的高性能的答案;
3.使用一对一关联添加数据
在实际开发中,我们经常会遇到表关联的情况,比如一张数据表的记录与另一张数据表记录一一对应,即:一一对应关系,此时我们对表数据的添加最好也应该是一次性关联添加的.Hibernate就提供了相关的方法,供开发人员处理这种关系的映射,下面就来学习一下.
此处,我们使用两张新表来进行学习,UserInfo和UserExtend,其中UserInfo记录用户的姓名,性别,出生日期等基础信息,UserExtend记录扩充信息,如职业,公司,地址等。UserInfo中通过一个UserExtend属性与UserExtend表相关联。具体如下:
/**
* Created by c-yangx on 11/18/2016.
*/
public class UserInfo {
private int id;
private String name;
private Timestamp birthday;
private String sex;
private UserExtend userExtend; public int getId() {return id;} public void setId(int id) {this.id=id;} public String getName() {return name;} public void setName(String name) {this.name = name;} public Timestamp getBirthday() {return birthday;} public void setBirthday(Timestamp birthday) {this.birthday = birthday;} public String getSex() {return sex;} public void setSex(String sex) {this.sex = sex;} public UserExtend getUserExtend() {return userExtend;} public void setUserExtend(UserExtend userExtend) {this.userExtend = userExtend;}
}
UserInfo.java
/**
* Created by c-yangx on 11/18/2016.
*/
public class UserExtend {
private int id;
private String position;
private String company;
private String address;
private UserInfo userInfo; public int getId() {return id;}
public void setId(int id) {this.id = id;} public String getPosition() {return position;} public void setPosition(String position) {this.position = position;} public String getCompany() {return company;} public void setCompany(String company) {this.company = company;} public String getAddress() {return address;} public void setAddress(String address) {this.address = address;} public UserInfo getUserInfo() {return userInfo;} public void setUserInfo(UserInfo userInfo) {this.userInfo = userInfo;}
}
UserExtend.java
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.UserInfo" table="userinfo" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true">
<comment>姓名</comment>
</column>
</property>
<property name="birthday" type="java.sql.Timestamp">
<column name="birthday" length="20" not-null="true">
<comment>出生日期</comment>
</column>
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="5" not-null="true">
<comment>性别:w=女;m=男;</comment>
</column>
</property>
<many-to-one name="userExtend" column="userExtend" unique="true" not-null="true" cascade="all"></many-to-one>
</class>
</hibernate-mapping>
UserInfo.hbm.xml
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.UserExtend" table="userextend" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="position" type="java.lang.String">
<column name="position" length="50" not-null="false">
<comment>职位</comment>
</column>
</property>
<property name="company" type="java.lang.String">
<column name="company" length="200" not-null="false">
<comment>公司名</comment>
</column>
</property>
<property name="address" type="java.lang.String">
<column name="address" length="50" not-null="false">
<comment>住址</comment>
</column>
</property>
<one-to-one name="userInfo" property-ref="userExtend"></one-to-one>
</class>
</hibernate-mapping>
UserExtend.hbm.xml
测试代码为:
@org.junit.Test
public void save_one2one() throws ParseException {
//创建对象
UserInfo userInfo=new UserInfo();
UserExtend userExtend=new UserExtend();
userExtend.setPosition("IT");
userExtend.setCompany("guess");
userExtend.setAddress("BeiJing CangPing");
userInfo.setName("andrew"); SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
userInfo.setBirthday(new Timestamp(simpleDateFormat.parse("1992-01-10").getTime())); userInfo.setSex("m");
userInfo.setUserExtend(userExtend); Session session=null;
Transaction tx=null;
try{
session= HibernateUtil.openSession();
tx=session.beginTransaction(); session.save(userInfo); tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
session.close();
}
}
从细分类上,此种属于"唯一外键双向关联",其他的还有"多对一单向关联"、"多对多单向关联"等,这个话题内容较多,就不在此处展开,后面也许会单开一篇文章研究一下.
对了,最后一定别忘了在主配置文件hibernate.cfg.xml中添加mapping配置。
放一张数据库截图,生成表结构如图所示:
4.一对多关联添加数据.
还有一种开发中常见的需求是,表的一对多关心,举个生活中的例子:一个支付宝账号绑定多张银行卡,每张卡都会显示他自己是哪个银行的,卡号是多少...等信息;
那么我们这里就用两张新表来演示,一张账户表(Account),类比于支付宝账户;一张绑定银行卡表(BindCard),记录例子中的绑定银行卡信息;一个账户会对应有多条绑定银行卡记录.
a> 两个model类的代码如下:
/**
* Created by c-yangx on 11/18/2016.
*/
public class Account { private int id;
private String name;
private Set<BindCard> bindCards; public int getId() {return id;} public void setId(int id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} public Set<BindCard> getBindCards() {return bindCards;} public void setBindCards(Set<BindCard> bindCards) {this.bindCards = bindCards;}
}
Account.java
/**
* Created by c-yangx on 11/18/2016.
*/
public class BindCard {
private int id;
private String cardNum;
private int cardType; private Account account; public int getId() {return id;} public void setId(int id) {this.id = id;} public String getCardNum() {return cardNum;} public void setCardNum(String cardNum) {this.cardNum = cardNum;} public int getCardType() {return cardType;} public void setCardType(int cardType) {this.cardType = cardType;} public Account getAccount() {return account;} public void setAccount(Account account) {this.account = account;}
}
BindCard.java
b>Account.hbm.xml;
其中有几点需要特别说明一下:
1.在映射文件里,通过<set>标签配置一对多的关系映射;
2.cascade属性设置的是级联操作类型,设置为all时,是所以操作都能执行; 如果只进行"创建"和"修改",也可设置成save-update;
3.<set>标签的name属性值=持久化类对应的属性名; <key>的column属性值=与其关联的表的外键;
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.Account" table="account" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true">
<comment>账户名</comment>
</column>
</property>
<set name="bindCards" cascade="all" lazy="false">
<key column="cardId"/>
<one-to-many class="models.BindCard"/>
</set>
</class>
</hibernate-mapping>
c>最后是测试代码,这就没啥好多说的了
@org.junit.Test
public void save_one2many(){
BindCard bindCard1=new BindCard();
bindCard1.setCardNum("1234343242");
bindCard1.setCardType(0); BindCard bindCard2=new BindCard();
bindCard2.setCardNum("3421213131");
bindCard2.setCardType(1); Set<BindCard> set=new HashSet<>();
set.add(bindCard1);
set.add(bindCard2); Account account=new Account();
account.setName("andrew's account");
account.setBindCards(set); Session session=null;
Transaction tx=null;
try{
session= HibernateUtil.openSession();
tx=session.beginTransaction(); session.save(account); tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
session.close();
}
}
生成的数据表结构:
二) 查(R)
方式一:根据主键id,查询单条记录,这也是最简单的方式;
Session session=HibernateUtil.openSession();
Feedback feedback= session.get(Feedback.class,60);
方式二:HQL(hibernate query language)查询;
1.HQL查询语言是什么? HQL查询语言是面向对象查询语言,支持多态查询; 当我们想在查询时,做一些复杂的逻辑,比如where 筛选,order by 排序等,HQL就顶上用了;
Session session= HibernateUtil.openSession();
String sqlStr="from Feedback";
Query q=session.createQuery(sqlStr);
List<Feedback> feedbacks=q.list();
做条件筛选时,修改下sqlStr就行:
public List<Feedback> getAll(String userName) {
Session session = null;
try {
session = HibernateUtils.getSession();
Query q =session.createQuery("from Feedback where userName=?");
// 注意:参数索引从0开始
q.setParameter(0, userName);
// 执行查询
return q.list();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
session.close();
}
}
方式三:QBC(Query By Criteria)查询;
1)Hibernate 5.2版本之前(暂时还没有核实是5.2之前的哪一个版本开始),
使用QBC查询,通常有3个步骤:
1.用Session实例的createCriterria()方法创建Criteria对象c;
2.使用Restrictions工具类的相关方法为创建的对象c设置查询条件。
常见的方法有: a) Restrictions.eq = 等于;
b) Restrictions.allEq = 使用Map、key/value进行多个等于的对比;
c) Restrictions.gt = 大于;
d) Restrictions.ge = 大于等于;
e) Restrictions.ct = 小于;
f) Restrictions.le = 小于等于;
g) Restrictions.between = 对应SQL的between子句;
h) Restrictions.like = 对应SQL的like 子句;
i) Restrictions.in = 对应SQL 的in子句;
3.使用对象c的list()方法执行查询,获取结果;
2) Hibernate 5.2版本时,createCriteria()方法已经过时了,新版中使用的是链式的查询语句(类似C#中的linq to sql,还有现在android中的rxjava,看来,链式编程以其优美的代码风格,便于维护的特性,越来越成为潮流)
下面放一段核心代码 (可能因为h5.2版本较新,关于createCriteria()替代方法的查询结果,在百度上暂时很难找到,这个地方也是费了老大劲了. ):
@org.junit.Test
public void get_qbc(){
Session session= HibernateUtil.openSession();
//在Hibernate 5.2中,此方法过时了
//Criteria criteria=session.createCriteria(Feedback.class); //用新的替代方法
CriteriaBuilder cBuilder=session.getCriteriaBuilder();
CriteriaQuery<Feedback> cQuery= cBuilder.createQuery(Feedback.class);
Root<Feedback> feedbackRoot=cQuery.from(Feedback.class); //1.select all records
CriteriaQuery<Feedback> select = cQuery.select(feedbackRoot);
TypedQuery<Feedback> typedQuery = session.createQuery(select);
List<Feedback> resultlist = typedQuery.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_
**/ //2.Ordering the records
CriteriaQuery<Feedback> select1 = cQuery.select(feedbackRoot);
select1.orderBy(cBuilder.asc(feedbackRoot.get("id")));
TypedQuery<Feedback> typedQuery1 = session.createQuery(select1);
List<Feedback> resultlist1 = typedQuery1.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_ order by feedback0_.id asc
* */ //3.where select条件筛选查询
CriteriaQuery<Feedback> select2 = cQuery.select(feedbackRoot);
select2.orderBy(cBuilder.asc(feedbackRoot.get("id")));
select2.where(cBuilder.ge(feedbackRoot.get("id"),60));
TypedQuery<Feedback> typedQuery2 = session.createQuery(select2);
List<Feedback> resultlist2 = typedQuery2.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_ where feedback0_.id>=60 order by feedback0_.id asc
* */ System.out.println("result ok");
}
三) 改(U)、删(D)
相较于"CR",修改和删除的需求相对就比较简单了,没有那么多的复杂需求,这个地方就简单带过了;
//修改(updateInstance=要修改的实例)
session.update(updateInstance);
//删除(deleteInstance=要删除的实例)
session.delete(deleteInstance);
后言
呼~~总算能松口气了。。。
真正写的时候,才发现, "crud",叫起来多么简单的一个单词,中间的文章何其多,深挖起来,几天几夜也说不完; hibernate一个流行的框架,里面的内容又是何其多,博主实在是不敢继续继续深入下去了,否则这篇文章发表不知要到何年何月去了(哈哈~~开个玩笑)...
文章内容虽然不深,不过博主是在用心写,里面的每一段代码,都是测试运行,确认无误的...(自己受够了网上前言不搭后语的demo代码,骂过... 同样原因,可不想自己也被参考了文内代码的人在背后骂^_^)如果大家发现什么问题,也欢迎评论,有问题的地方,我会及时修正;
文章写着挺耗时的,不过楼主会坚持下去。理由只有两个:1.如果你也刚开始学Hibernate,本文能让你觉得多少有些收获,我就会觉得自己的没有做无用功; 2.博主自己忘了的时候,业可以回头来翻看;
也欢迎大家关注,共同学习,共同进步.
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利;
本文出自:博客园--别问是谁
SSH初体验系列--Hibernate--2--crud操作的更多相关文章
- SSH初体验系列--Hibernate--1--环境配置及demo
最近在学hibernate,常见的教程都是搭配mysql,因为公司本地电脑用的是pg,所以就尝试着做个pg的小demo. 自己也是边学边写,只当是加深印象.话不多说,直接开始; 一) 准备工作; 1) ...
- SSH初体验系列--Hibernate--3--单值与分页查询
前言 查询可以按结果集分2类:单个结果 和 数组 ; 其中,返回数组,在这个 数据库数据量随随便便就能上几十万的互联网时代大背景下,常常需要做分页处理, 所以这里就说一下单值和分页, 算是对上一篇&q ...
- hibernate的CRUD操作
一对多关系映射的crud操作: 1.单项的保存操作 /** * 保存操作 * 正常的保存:创建一个联系人,需要关联客户 */ @Test public void test1(){ Session s= ...
- hibernate之CRUD操作
CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...
- java框架篇---hibernate之CRUD操作
CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...
- 初窥MyBatis-普通的CRUD操作
编写接口 编写对应的Mapper.xml中的sql语句 测试(增删改需要提交事务) <mapper namespace="com.perwrj.dao.UserMapper" ...
- hibernate--CRUD初体验
hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.per ...
- ipython及Python初体验
阅读目录: Python环境体验 Python编辑器 ipython安装 Python提示符 Python初体验 print和变量 变量操作 内建函数:方法 数学运算:简单算术.随机数 关于模块 一. ...
- 【SSH三大框架】Hibernate基础第五篇:利用Hibernate完毕简单的CRUD操作
这里利用Hibernate操作数据库完毕简单的CRUD操作. 首先,我们须要先写一个javabean: package cn.itcast.domain; import java.util.Date; ...
随机推荐
- QSignalMapper类的使用
Qt中当定义了非常多的button,而他们的信号都同样时(比方都是点击信号),没有必要给他们每一个都设置信号和槽的链接.QSignalMapper给我们攻克了这个难题. 今天完毕这个相似的功能时,不知 ...
- JQuery的get、post和ajax方法的使用
在JQuery中可以使用get,post和ajax方法给服务器端传递数据 get方法的使用(customForGet.js文件): function verify(){ //1.获取文本框的数据 // ...
- MyEclipse 集成 Gradle开发环境
一.上Grandle官网下载Gradle,地址:http://www.gradle.org/downloads 如果只是运行只下载gradle-2.6-bin.zip 就可以了,如果为了扩展开发的话就 ...
- $(document).ready()方法和window.onload()方法
$(document).ready()方法和window.onload()方法 $(document).ready()方法是JQuery中的方法,他在DOM完全就需时就可以被调用,不必等待这些元素关联 ...
- javascript闭包传参就这么简单
var query = (function (a) { return a; })('fx'); alert(query);
- [springMVC - 1A] - Request processing failed; nested exception is org.apache.ibatis.builder.IncompleteElementException
一月 14, 2016 1:30:07 下午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() for ...
- (五)Lucene——中文分词器
1. 什么是中文分词器 对于英文,是安装空格.标点符号进行分词 对于中文,应该安装具体的词来分,中文分词就是将词,切分成一个个有意义的词. 比如:“我的中国人”,分词:我.的.中国.中国人.国人. 2 ...
- Mysql报错......\xE6\x80\xBB\xE7\x9B\x91' for column...
Mysql添加表中字符报错:Incorrect string value: '\xE6\x80\xBB\xE7\x9B\x91' for column 'postName' at row 1 原因:字 ...
- To Use Genymotion
Chinese Site:http://www.genymotion.cn/ Offical Site:http://www.genymotion.com/ Not available in Chi ...
- 贪吃蛇easyx版本
这学期学了图形交互学,三个星期下来,突然意识到已经可以用c++写一个贪吃蛇了. 于是就用了两天写了这个小游戏. 其中一天写了核心代码,半天找核心代码中的bug,还有半天进行了界面及操作的优化. 但是有 ...