107. 普通属性映射 - property
可使用的常见属性如下:
name – 对应类的属性名称
type – 指定属性的类型,一般情况下可以不用指定,由hibernate自动匹配(可参考文档中的有关说明)
length – 指定长度
column – 指定属性所对应的数据库字段的名称,如果不指定,就是属性的名称
108. 多对一关联映射 - many-to-oneUser-Group 多个用户属于某个组
从代码上体现为:
public class Group {
privte String id;
private String name;
…..
}
public class User{
private String id;
privte String name;
……
private Group group;
public Group getGroup(){return group;}
public void setGroup(Group group){
this.group = group;
}
……
}
109. many-to-one映射的编写many-to-one的映射最常用,也是最容易理解和编写的
生成的DDL语句如下
create table T_Group (id varchar(255) not null, name varchar(255), primary key (id))
create table User (id varchar(255) not null, name varchar(255), password varchar(255), createTime datetime, expireTime datetime, groupid varchar(255), primary key (id))
alter table User add index FK285FEBC3D18669 (groupid), add constraint FK285FEBC3D18669 foreign key (groupid) references T_Group (id)
从生成的DDL语句,我们可以知道,实际上是在User表上建立了一个指向Group表的外键关联
111. cascade实际上意味着什么?无cascade配置的User-Group执行代码
配置
java代码:
Group group = new Group();
group.setName("jkjk");
User user = new User();
user.setName("管理员");
user.setGroup(group);
session.save(user);
执行结果:
抛出org.hibernate.TransientObjectException异常,以上代码中,group对象是一个瞬时对象,user对象引用了一个瞬时对象,所以在保存的时候出现异常
112. 无cascade配置时正确的java执行代码为避免异常,我们可以需要将group对象保存
Group group = new Group();
group.setName("jkjk");
//执行save操作之后,group对象变成持久化对象的状态
session.save(group);
User user = new User();
user.setName("管理员");
user.setGroup(group);
session.save(user);
113. 添加cascade配置
下面的代码(最初的代码)
Group group = new Group();
group.setName("jkjk");
User user = new User();
user.setName("管理员");
user.setGroup(group);
session.save(user);
可正确执行
cascade配置,使得hibernate在管理对象的时候,对cascade对象执行了级联操作
115. 一对一 (主键关联映射)Person类
public class Person {
private int id;
private IdCard idCard;
…..
}
映射文件
idCard
….
IdCard类
public class IdCard {
private int id;
private Person person;
……
}
映射文件
….
116. 一对一 (唯一外键关联映射)Mankind类
public class Mankind {
private String id;
private String name;
private Nose nose;
关联映射
Nose类
public class Nose {
private String id;
private Mankind mankind;
关联映射
property-ref:在这种情况下,必须指定此属性,它表示本类(Nose)的主键将会与关联类(Mankind)的此属性(nose)相对应
117. 一对多关联映射 (one-to-many)在对象模型中,一对多的关联关系,使用集合来表示
比如Classes(班级)和Student(学生)之间是一对多的关系
public class Classes {
private String id;
private String name;
private Set students;
….
public class Student {
private String id;
private String name;
…..
130. 例子:从Java代码看group-user双向关联的inverse概念:inverse用来标识双向关联的关联关系由哪一端维护。默认inverse的值为false,由主动方负责维护关联关系;如果设为true,则由反向一端维护关联关系。
用例:我们假设已经有一个Group类的实例:adminGroup,现在我们要新增一个用户,并且将用户分配到adminGroup中。
inverse=“false”,由主动方Group负责维护group-user的关联关系.
User user = new User(“Jak”);
adminGroup.getUsers.add(user);
session.save(user); session.update(group);
inverse=“true”,由Group的反向段User负责维护关联关系。
User user = new User(“Jak”);
user .setGroup(adminGroup); session.save(user);
134. 例子: Hibernate语言查询(Hibernate Query Language,HQL)简单例子:查询用户名以“J”开头的所有用户。
Query query = session.createQuery(
"from User user where user.name like 'J%'");
List users = query.list();
复杂例子:从User和Group中查找属于“admin”组的所有用户。
Query query = session.createQuery(
“from User user where user.group.name=‘admin’”);
如果用传统的SQL则查询语句如下:
select user.userId as userId, user.name as name, user.groupId as groupId, user.idCardId as idCardId from TBL_USER user, TBL_GROUP group where (group.groupName='admin' and user.groupId=group.groupId)
153. Sample接口及其实现接口定义
public interface Sample{
public int compute(int i,int j);
}
接口的实现一
public class SampleImpl1 implements Sample {
public int compute(int i,int j){
return i + j;
}
}
接口的实现二
public class SampleImpl2 implements Sample {
public int compute(int i,int j){
return i * j;
}
}
ClientTest.java无需改动
只需改动ApplicationContext.xml的配置,即可实现实际功能的切换
155. Book.javapublic class Book {
private String name;
private String author;
/**
* @return Returns the author.
*/
public String getAuthor() {
return author;
}
/**
* @param author The author to set.
*/
public void setAuthor(String author) {
this.author = author;
}
//other getters/setters…
}
156. BookFinderBookFinder接口
public interface BookFinder {
public List findAll();
}SimpleBookFinderImpl
public class SimpleBookFinderImpl implements BookFinder{
/**
* @see com.bjsxt.spring.BookFinder#findAll()
*/
public List findAll() {
List books = new ArrayList();
for(int i=0; i<20; i++){
Book book = new Book();
book.setName("book"+i);
book.setAuthor("author"+i);
books.add(book);
}
return books;
}
}
157. BookListerBookList接口
public interface BookLister{
public Book[] findBooks(String name);
}BookListerImpl实现代码
public class BookListerImpl implements BookLister {
BookFinder finder;
public BookListerImpl() {
finder = new SimpleBookFinderImpl();
}
public Book[] findBooks(String name){
List books = finder.findAll();
for (Iterator iter = books.iterator(); iter.hasNext();) {
Book book = (Book) iter.next();
if(!book.getName().equals(name)){
iter.remove();
}
}
return (Book[])books.toArray(new Book[books.size()]);
}
160. FileBookFinderImpl – 从文件系统读取Book的信息public class FileBookFinderImpl implements BookFinder {
public List findAll() {
String file = “d:/test.txt”;
List books = new ArrayList();
try {
BufferedReader in
= new BufferedReader(new FileReader(file));
String line = null;
while( (line = in.readLine()) != null)
{
String[] sp = line.split(";");
if(sp.length == 2){
… Book book = new Book();
book.setName(sp[0]);
book.setAuthor(sp[1]);
books.add(book);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return books;
}
}
161. 现在需要做什么?我们的客户代码调用BookLister
BookLister如何调用BookFinder?下面是以前初始化BookFinder的代码:
public BookListerImpl() {
finder = new SimpleBookFinderImpl();
}
现在,我们必须改动这段代码:
public BookListerImpl() {
finder = new FileBookFinderImpl();
}
看出问题来了吗?
187. CharacterEncodingFilter如何提交中文字符?
配置web.xml了,Spring提供了专门的针对Encoding的过滤器
配置方法如下:
Spring character encoding filterorg.springframework.web.filter.CharacterEncodingFilterencodingGBKSpring character encoding filter/*