<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    京山游俠

    專注技術,拒絕扯淡
    posts - 50, comments - 868, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    在這里,將創建一個簡化的用戶管理模塊,演示怎樣利用SpringSide提供的數據持久層的功能,包括怎樣通過Hibernate的Annotation來配置多對一映射和多對多映射。

    大家都知道,現在最流行用戶管理模型的是RBAC,也就是基于角色的訪問控制模型,在這種模型中,可以劃分多個層次,如用戶-角色-資源、用戶-角色-權限-資源、用戶-角色-角色組-權限-資源、用戶-角色-角色組-權限-操作-資源等等,因此,想要創建一個完善而復雜的用戶管理模塊,是相當具有難度的。在Web2.0時代,有一個很重要的開發思想,那就是先讓程序跑起來,以后再逐步添加復雜的功能。因此,在這里只創建一個簡化的用戶管理模塊。

    所謂簡化,它具有如下幾個特點:

    1.在認證方式中,選擇基于用戶名和密碼的認證,用戶需要提供用戶名、密碼和昵稱,用戶名和昵稱都要求不能重復,用戶名不能包含中文,且不能夠被修改,昵稱可以為中文,也可以被修改。密碼使用MD5加密。

    2.不包含用戶的真實信息,如姓名、年齡、性別、職業、地址、郵編等等,因為如果包含這些字段,那么還需要包含更多的額外字段來讓用戶決定是否公開這些信息,因此,去掉這些東西,可以簡化開發過程,讓網站能夠盡快的跑起來。

    3.聯系方式只需要用戶提供它的電子郵箱和QQ號碼。

    4.如果用戶密碼丟失,可以通過密碼提示問題找回,隨機產生的新密碼會發到用戶的電子郵箱。

    5.省略用戶的個性化設置,如個性化簽名、自定義頭像等。

    6.要能夠記錄用戶的注冊時間和最后登錄時間。

    7.要具有完善的積分和排名機制。

    8.用戶刪除的時候不做物理刪除,只標記為該用戶不可用。

    8.具有簡化的角色和權限管理機制,這里的簡化主要有以下幾點:每個用戶只能屬于一個角色,即多對一關系,而不是傳統的多對多關系;角色不需要分組;沒有專門的資源抽象層;在角色表中只使用一個字段來表示該角色具有的權限,權限以數字表示,以逗號分開,如“1,2”,“1,3,15”等等。

    9.用戶可以創建群和加入群,為了簡化,群的創始人即為管理員,并不可改變,用戶加入群需要管理員批準,一個用戶可以加如多個群,即多對多關系。

    從上面的描述可以看出,一個簡化的用戶管理系統最少需要三個表,即users,roles和groups表,其中users和roles之間為多對一映射,users和groups之間為多對多映射,為了實現多對多映射,并且用戶加入群的時候需要管理員批準,需要一個中間表users_groups。下面是在MySQL中創建數據表的語句。

    創建用戶表:

    create ? table ?users(
    id?
    int ? not ? null ?auto_increment? primary ? key ,
    name?
    varchar ( 20 )? not ? null ,
    password?
    char ( 32 )? not ? null ,
    monicker?
    varchar ( 30 )? not ? null ,
    question?
    varchar ( 30 )? not ? null ,
    answer?
    varchar ( 30 )? not ? null ,
    email?
    varchar ( 40 )? not ? null ,
    qq?
    varchar ( 12 )? not ? null ,
    roleid?
    int ? not ? null ,
    score?
    int ? not ? null ? default ? ' 0 ' ,
    regtime?
    timestamp ? not ? null ? default ? CURRENT_TIMESTAMP ,
    logintime?
    timestamp ? not ? null ? default ? ' 2007-01-01?00:00:00 ' ,
    isdeleted?
    varchar ( 2 )? not ? null ? default ? ' 0 ' ,
    index (username),
    index (monicker));


    為了加快查找用戶的速度,在用戶名和昵稱列上創建了索引。

    創建角色表:

    create ? table ?roles(
    id?
    int ? not ? null ?auto_increment? primary ? key ,
    name?
    varchar ( 20 )? not ? null ,
    privilegesFlag?
    varchar ( 255 ),
    index (rolename)
    );


    創建群組表:

    create ? table ?groups(
    id?
    int ? not ? null ?auto_increment? primary ? key ,
    name?
    varchar ( 40 )? not ? null ,
    creatorid?
    int ? not ? null ,
    createtime?
    timestamp ? not ? null ? default ? CURRENT_TIMESTAMP ,
    isdeleted?
    varchar ( 2 )? not ? null ? default ? ' 0 ' ,
    index (groupname));


    creatorid代表組的創始人,同時也是管理員,這里同樣設置群組不做物理刪除。

    創建用戶群組多對多映射輔助表:

    create ? table ?users_groups(
    id?
    int ? not ? null ?auto_increment? primary ? key ,
    userid?
    int ? not ? null ,
    groupid?
    int ? not ? null ,
    jointime?
    timestamp ,
    status?
    tinyint ,
    index (userid),
    index (groupid)
    );


    其中status列代表用戶是否通過了管理員的批準,為了加快查找速度,在userid和groupid列上建立索引。

    設計完數據庫,就該設計領域對象了,領域對象的設計方法為先設計簡單的POJO,然后再在POJO上添加Hibernate Annotation來配置映射關系。在進行Annotation配置的時候,可以從以下幾個方面進行思考。

    1、使用什么樣的數據類型映射數據庫中的列類型?
    2、對象之間是一對一、一對多還是多對多關系?
    3、關聯的對象之間哪一個作為主控方?
    4、對象之間的關聯是單向的還是雙向的?

    首先來看看users和roles之間的關系,考慮到加載一個用戶數據的時候,往往同時需要知道他屬于哪個角色,而加載一個角色的時候,就沒有必要知道它管理哪些用戶了,因此,它們是簡單的單向關系,是多對一映射。當出現多對一映射的時候,永遠都應該選擇多的這一方作為主控方,道理很簡單,打個比方,讓一個國家元首記住全國人民的名字基本是不可能的,而讓全國人民記住國家元首的名字就很簡單了。因此,這里User作為主控方,Role作為被控方。

    再來看看數據類型的映射,對于簡單的int、varchar這樣的就不用多說了。而日期時間類型的映射是一個重點,可以看到,前面的數據庫創建語句中,所有需要時間的地方都使用了timestamp列類型,使用timestamp列類型的唯一目的就是為了能夠使用default CURRENT_TIMESTAMP語句,使用date和datetime類型就不行,在MySQL中,timestamp只能表示從'1970-01-01 00:00:00'到2037年的范圍。

    MySQL中的timestamp和java.sql.Timestamp表現不一致,在MySQL中,timestamp和datetime類型精度是一樣的,都只能儲存到整數秒,而timestamp比datetime能表示的時間范圍要小得多,在Java中,java.util.Date和MySQL的timestamp的精度是一致的,只能儲存到整數秒,而java.sql.Timestamp還保存毫微秒,因此建議使用java.util.Date來映射timestamp列,使用java.sql.Timestamp只是浪費。

    MySQL和Java在時間上面還有一個沖突,那就是MySQL支持全零的時間,如'0000-00-00 00:00:00',而Java不支持,因此如果在定義users表的logintime列時使用logintime timestamp not null default '0000-00-00 00:00:00',那么在使用Hibernate來獲取User對象的時候就會出錯,所以在創建數據庫的時候要選擇一個合法的默認時間,如'2007-01-01 00:00:00'。

    下面請看User.java的代碼:

    package ?com.xkland.domain;

    import ?java.io.Serializable;
    import ?java.util.Date;
    import ?org.springside.core.dao.extend.Undeletable;
    import ?org.hibernate.annotations.Cache;
    import ?org.hibernate.annotations.CacheConcurrencyStrategy;
    import ?javax.persistence. * ;

    @Entity
    @Table(name
    = " users " )
    @Undeletable(status
    = " isDeleted " )
    public ? class ?User? implements ?Serializable? {
    ?
    private ?Integer?id;
    ?
    private ?String?name;
    ?
    private ?String?password;
    ?
    private ?String?monicker;
    ?
    private ?String?question;
    ?
    private ?String?answer;
    ?
    private ?String?email;
    ?
    private ?String?qq;
    ?
    private ?Role?role;
    ?
    private ?Integer?score;
    ?
    private ?Date?regTime;
    ?
    private ?Date?loginTime;
    ?
    private ?Byte?isDeleted;
    ?
    ?@Id
    ?@GeneratedValue(strategy?
    = ?GenerationType.AUTO)
    ?
    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?getPassword()? {
    ??
    return ?password;
    ?}

    ?
    public ? void ?setPassword(String?password)? {
    ??
    this .password? = ?password;
    ?}

    ?
    ?
    public ?String?getMonicker()? {
    ??
    return ?monicker;
    ?}

    ?
    public ? void ?setMonicker(String?monicker)? {
    ??
    this .monicker? = ?monicker;
    ?}

    ?
    ?
    public ?String?getQuestion()? {
    ??
    return ?question;
    ?}

    ?
    public ? void ?setQuestion(String?question)? {
    ??
    this .question? = ?question;
    ?}

    ?
    ?
    public ?String?getAnswer()? {
    ??
    return ?answer;
    ?}

    ?
    public ? void ?setAnswer(String?answer)? {
    ??
    this .answer? = ?answer;
    ?}

    ?
    ?
    public ?String?getEmail()? {
    ??
    return ?email;
    ?}

    ?
    public ? void ?setEmail(String?email)? {
    ??
    this .email? = ?email;
    ?}

    ?
    ?
    public ?String?getQq()? {
    ??
    return ?qq;
    ?}

    ?
    public ? void ?setQq(String?qq)? {
    ??
    this .qq? = ?qq;
    ?}

    ?
    ?@ManyToOne
    ?@JoinColumn(name
    = " roleid " )
    ?
    public ?Role?getRole()? {
    ??
    return ?role;
    ?}

    ?
    public ? void ?setRole(Role?role)? {
    ??
    this .role? = ?role;
    ?}

    ?
    ?@Column(name
    = " score " ,insertable = false )
    ?
    public ?Integer?getScore()? {
    ??
    return ?score;
    ?}

    ?
    public ? void ?setScore(Integer?score)? {
    ??
    this .score? = ?score;
    ?}

    ?
    ?@Column(name?
    = ? " regtime " ,insertable = false )
    ?@Temporal(TemporalType.TIMESTAMP)
    ?
    public ?Date?getRegTime()? {
    ??
    return ?regTime;
    ?}

    ?
    public ? void ?setRegTime(Date?regTime)? {
    ??
    this .regTime? = ?regTime;
    ?}

    ?
    ?@Column(name?
    = ? " logintime " ,insertable = false )
    ?@Temporal(TemporalType.TIMESTAMP)
    ?
    public ?Date?getLoginTime()? {
    ??
    return ?loginTime;
    ?}

    ?
    public ? void ?setLoginTime(Date?loginTime)? {
    ??
    this .loginTime? = ?loginTime;
    ?}

    ?
    ?@Column(name?
    = ? " isdeleted " ,insertable = false )
    ?
    public ?Byte?getIsDeleted()? {
    ??
    return ?isDeleted;
    ?}

    ?
    public ? void ?setIsDeleted(Byte?isDeleted)? {
    ??
    this .isDeleted? = ?isDeleted;
    ?}
    ?
    }

    這里只對幾個特殊的Annotation做一下注釋:
    1、因為創建數據表的時候使用的是users,而實體類為User,單復數不同引發名稱不一致,因此需要@Table(name="users");
    2、因為該表中的數據不做物理刪除,所以加上@Undeletable(status="isDeleted"),結合SpringSide提供的HibernateEntityExtendDao類,可以在調用remove方法的時候將isdeleted列設置為"-1";
    3、創建數據表的時候,所有的列名都是用的小寫字母,因此有的列映射需要明確指定,如@Column(name = "logintime",insertable=false);
    4、對于在創建數據表的時候定義了默認值的列,如regtime、regtime、logintime、isdeleted,在向數據庫中添加數據的時候,可以不在insert語句中指定這些列,而讓它們使用默認值,因此,需要告訴Hibernate在生成insert語句的時候不要包含這些列,可以使用insertable=false語句,如@Column(name = "regtime",insertable=false);
    5、指定時間精度,使用@Temporal(TemporalType.TIMESTAMP);
    6、指定users表通過roleid和roles表進行多對一映射,使用@ManyToOne和@JoinColumn(name="roleid")

    Role.java則比較簡單,如下:

    package ?com.xkland.domain;

    import ?java.io.Serializable;

    import ?javax.persistence.Entity;
    import ?javax.persistence.GeneratedValue;
    import ?javax.persistence.GenerationType;
    import ?javax.persistence.Id;
    import ?javax.persistence.Table;

    @Entity
    @Table(name
    = " roles " )
    public ? class ?Role? implements ?Serializable? {
    ?
    private ?Integer?id;
    ?
    private ?String?name;
    ?
    private ?String?privilegesFlag;
    ?
    ?@Id
    ?@GeneratedValue(strategy?
    = ?GenerationType.AUTO)
    ?
    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?getPrivilegesFlag()? {
    ??
    return ?privilegesFlag;
    ?}

    ?
    public ? void ?setPrivilegesFlag(String?privilegesFlag)? {
    ??
    this .privilegesFlag? = ?privilegesFlag;
    ?}

    }


    下一步再來看看users和groups之間的映射關系,不難想象,當載入一個用戶的資料時,往往需要知道他加入了哪些群,而載入一個群的資料時,往往需要知道它有哪些用戶,因此,他們之間是一個雙向的關系,同時,載入一個群的資料時,還需要知道它的管理員是誰,因此又同時存在一個單向的多對一關系。在多對多關系中,設定User為主控方,所以需要在User.java中添加如下代碼?

    private ?List < Group > ?groups;
    @ManyToMany(targetEntity
    = User. class ,
    ?cascade
    = {CascadeType.PERSIST,?CascadeType.MERGE} )
    @JoinTable(name
    = " users_groups " ,
    ?joinColumns
    = {@JoinColumn(name = " userid " )} ,
    ?inverseJoinColumns
    = {@JoinColumn(name = " groupid " )} )
    public ?List < Group > ?getGroups()? {
    ?
    return ?groups;
    }

    public ? void ?setGroups(List < Group > ?groups)? {
    ?
    this .groups? = ?groups;
    }


    而整個Group.java的代碼如下:

    package ?com.xkland.domain;

    import ?java.io.Serializable;
    import ?java.util.Date;
    import ?java.util.List;
    import ?org.springside.core.dao.extend.Undeletable;
    import ?org.hibernate.annotations.Cache;
    import ?org.hibernate.annotations.CacheConcurrencyStrategy;
    import ?javax.persistence. * ;

    @Entity
    @Table(name
    = " groups " )
    @Undeletable(status
    = " isDeleted " )
    public ? class ?Group? implements ?Serializable? {
    ????
    private ?Integer?id;
    ????
    private ?String?name;
    ????
    private ?User?creator;
    ????
    private ?Date?createTime;
    ????
    private ?String?isDeleted;
    ????
    ????
    private ?List < User > ?users;

    ????@Id
    ????@GeneratedValue(strategy?
    = ?GenerationType.AUTO)
    ????
    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;
    ????}

    ????
    ????@ManyToOne(cascade
    = {CascadeType.PERSIST,?CascadeType.MERGE} )
    ????@JoinColumn(name
    = " creatorid " )
    ????
    public ?User?getCreator()? {
    ????????
    return ?creator;
    ????}

    ????
    public ? void ?setCreator(User?creator)? {
    ????????
    this .creator? = ?creator;
    ????}

    ????
    ????@Column(name
    = " createtime " ,insertable = false )
    ????@Temporal(TemporalType.TIMESTAMP)
    ????
    public ?Date?getCreateTime()? {
    ????????
    return ?createTime;
    ????}

    ????
    public ? void ?setCreateTime(Date?createTime)? {
    ????????
    this .createTime? = ?createTime;
    ????}


    ????@Column(name
    = " isdeleted " ,insertable = false )
    ????
    public ?String?getIsDeleted()? {
    ????????
    return ?isDeleted;
    ????}

    ????
    public ? void ?setIsDeleted(String?isDeleted)? {
    ????????
    this .isDeleted? = ?isDeleted;
    ????}


    ????@ManyToMany(cascade
    = {CascadeType.PERSIST,?CascadeType.MERGE} ,
    ????????????mappedBy
    = " groups " ,
    ????????????targetEntity
    = User. class )
    ????
    public ?List < User > ?getUsers()? {
    ????????
    return ?users;
    ????}

    ????
    public ? void ?setUsers(List < User > ?users)? {
    ????????
    this .users? = ?users;
    ????}


    }

    ?

    好了,該開始測試了,看看經過前面設計和配置的代碼能否正常工作。首先,先創建三個Manager,這三個Manager都繼承自org.springside.core.dao.extend.HibernateEntityExtendDao,至于HibernateEntityExtendDao的功能,請參考SpringSide的文檔。代碼如下:
    UserManager.java:

    package ?com.xkland.manager;

    import ?org.springside.core.dao.extend.HibernateEntityExtendDao;
    import ?com.xkland.domain.User;

    public ? class ?UserManager? extends ?HibernateEntityExtendDao < User > ? {
    ?
    }



    RoleManager.java:

    package ?com.xkland.manager;

    import ?org.springside.core.dao.extend.HibernateEntityExtendDao;
    import ?com.xkland.domain.Role;

    public ? class ?RoleManager? extends ?HibernateEntityExtendDao < Role > ? {
    ?
    }


    GroupManager.java:

    package ?com.xkland.manager;

    import ?org.springside.core.dao.extend.HibernateEntityExtendDao;
    import ?com.xkland.domain.Group;

    public ? class ?GroupManager? extends ?HibernateEntityExtendDao < Group > ? {

    }


    下一步,將User.class、Role.class、Group.class等領域對象添加到src\main\resources\config\hibernate.cfg.xml中,如下:

    <! DOCTYPE?hibernate-configuration?PUBLIC
    ????????"-//Hibernate/Hibernate?Configuration?DTD?3.0//EN"
    ????????"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
    >

    < hibernate-configuration >
    ????
    < session-factory >
    ????????
    < mapping? class ="com.xkland.domain.Role" />
    ????????
    < mapping? class ="com.xkland.domain.User" />
    ????????
    < mapping? class ="com.xkland.domain.Group" />
    ????
    </ session-factory >
    </ hibernate-configuration >


    再下一步,將上面的三個Manager類交給Spring管起來,配置src\main\resources\spring\serviceContext.xml,如下:

    <? xml?version="1.0"?encoding="UTF-8" ?>
    <! DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN?2.0//EN"?"http://www.springframework.org/dtd/spring-beans-2.0.dtd" >
    < beans? default-lazy-init ="true" ?default-autowire ="byName" >
    ????
    < bean? id ="roleManager" ?class ="com.xkland.manager.RoleManager" />
    ????
    < bean? id ="userManager" ?class ="com.xkland.manager.UserManager" />
    ????
    < bean? id ="groupManager" ?class ="com.xkland.manager.GroupManager" />
    </ beans >


    最后一步,編寫一個Action類,用Spring將上面的三個Manager注入到Action中,測試能否順利的操作數據庫。Action類的代碼如下:

    package ?com.xkland.action;

    import ?org.apache.struts.action.Action;
    import ?org.apache.struts.action.ActionForward;
    import ?org.apache.struts.action.ActionForm;
    import ?org.apache.struts.action.ActionMapping;
    import ?javax.servlet.http.HttpServletRequest;
    import ?javax.servlet.http.HttpServletResponse;
    import ?com.xkland.manager. * ;
    import ?com.xkland.domain. * ;

    public ? class ?WelcomeAction? extends ?Action? {
    ?
    private ?RoleManager?roleManager;
    ?
    private ?UserManager?userManager;
    ?
    private ?GroupManager?groupManager;
    ?
    ?
    // 以下代碼的作用是注入三個Manager
    ? public ? void ?setUserManager(UserManager?userManager)? {
    ??
    this .userManager? = ?userManager;
    ?}


    ?
    public ? void ?setRoleManager(RoleManager?roleManager)? {
    ??
    this .roleManager? = ?roleManager;
    ?}

    ?
    ?
    public ? void ?setGroupManager(GroupManager?groupManager) {
    ??
    this .groupManager? = ?groupManager;
    ?}

    ?
    ?
    public ?ActionForward?execute(
    ???ActionMapping?mapping,
    ???ActionForm?form,
    ???HttpServletRequest?request,
    ???HttpServletResponse?response
    ???)
    {
    ??
    ??
    // 以下代碼測試能否添加role
    ??Role?role? = ? new ?Role();
    ??role.setName(
    " 第一個角色 " );
    ??role.setPrivilegesFlag(
    " 1,2,3,4, " );
    ??roleManager.save(role);
    ??
    ??
    // 以下代碼測試能否添加user
    ??User?user? = ? new ?User();
    ??user.setAnswer(
    " aa " );
    ??user.setEmail(
    " aa " );
    ??user.setQq(
    " aa " );
    ??user.setName(
    " abcdefg " );
    ??user.setPassword(
    " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " );
    ??user.setQuestion(
    " aa " );
    ??user.setMonicker(
    " abcdefg " );
    ??user.setRole(roleManager.get(
    1 ));
    ??userManager.save(user);
    ??
    ??
    // 以下代碼測試能否添加group
    ??Group?group? = ? new ?Group();
    ??group.setName(
    " 第一個用戶組 " );
    ??group.setCreator(user);
    ??groupManager.save(group);
    ??
    ??
    // 以下代碼測試將user和group建立關聯
    ??user? = ?userManager.get( 1 );
    ??group?
    = ?groupManager.get( 1 );
    ??user.getGroups().add(group);
    ??group.getUsers().add(user);
    ??userManager.save(user);
    ??groupManager.save(group);
    ??
    ??
    // 重定向到
    ?? return ? new ?ActionForward( " /welcome.jsp " );
    ?}

    }



    怎樣配置Action這里就不用多嘴了,請參考SpringSide的文檔。這里還要說一句,一定要記得修改src\main\resources\spring\applicationContext.xml中的事務配置中的package,否則運行會出錯,配置文件片斷如下:

    <!-- ?以AspectJ方式?定義?AOP? -->
    ????
    < aop:config? proxy-target-class ="true" >
    ????????
    <!-- ?注意,請把第2個*號換為項目package? -->
    ????????
    < aop:advisor? pointcut ="execution(*?*..manager.*Manager.*(..))" ?advice-ref ="txAdvice" />
    ????????
    < aop:advisor? pointcut ="execution(*?org.springside.core.dao.*Dao.*(..))" ?advice-ref ="txAdvice" />
    ????
    </ aop:config >

    ????
    <!-- ?基本事務定義,使用transactionManager作事務管理,默認get*方法的事務為readonly,其余方法按默認設置.
    ?????????????默認的設置請參考Spring文檔事務一章.?
    -->
    ????
    < tx:advice? id ="txAdvice" >
    ????????
    < tx:attributes >
    ????????????
    < tx:method? name ="get*" ?read-only ="true" />
    ????????????
    < tx:method? name ="find*" ?read-only ="true" />
    ????????????
    < tx:method? name ="*" />
    ????????
    </ tx:attributes >
    ????
    </ tx:advice >


    ?如果有興趣,還可以把hibernate.show_sql設置為true,以便觀察Hibernate生成的SQL語句,如下圖:
    29.JPG


    評論

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-01-05 17:15 by cc[匿名]
    so fast!
    加油,跟著你的springside系列文章學到了很多東西!

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-01-05 18:59 by suwu
    非常好,明白多了。。。。。

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-01-08 00:02 by willlim
    你真棒,希望你能繼續寫這么好的文章,會跟著一起學習的

    # 再談一下數據庫的備份策略  回復  更多評論   

    2007-01-09 17:48 by 海邊沫沫
      開發一個Web系統,在決定好使用什么開發技術和使用什么應用服務器之后,接下來的事情就應該考慮數據怎樣儲存的問題了。使用數據庫自然是不二的選擇,在這里,我選擇MySQL 5.0以上的版本。數據庫中僅存儲文本信息和上傳的圖片保存為什么文件名和屬于哪個用戶,而圖片文件則一律保存在硬盤上。

      首先,我把MySQL的數據目錄改到一個單獨的磁盤分區,這樣,當我重裝應用軟件的時候就不會影響到數據。先在E:/盤創建一個目錄MySQL_Data,然后打開MySQL安裝目錄下的my.ini文件,修改修改[mysqld]節的配置:
      datadir="E:/MySQL_Data/"

      下一步就是做一個數據備份的策略,既然我已經決定要把所有數據永久保存,那么數據備份就是非常重要的一件事情了,只有經常備份,才能防止意外造成數據丟失。我做的備份策略是這樣的:
      1.數據庫引擎選擇InnoDB,盡管它比MyISAM引擎要慢3-5倍,但是它是事務安全的,而且在服務器異常崩潰后,再次重啟服務器可以自動修復受損的數據表,這樣修改配置文件:
      default-storage-engine=INNODB
      2.創建專門的文件夾來儲存InnoDB的表空間文件和日志文件,在數據目錄下創建一個ibdata文件夾,并如下修改配置文件:
      innodb_data_home_dir = ./ibdata
      innodb_log_group_home_dir = ./ibdata
      innodb_data_file_path=ibdata1:50M:autoextend:max:1G

      這里我們先創建一個表空間文件,初始大小為50M,并可以自動增長,最大文件大小限制為1G,達到最大值之后,我們可以再添加一個表空間文件。
      3.固定時間備份,比如客流量不大的時候,可以每周備份一次,客流量大的時候可以每天備份一次。第一次備份時,使用mysqldump做一個完全備份,以后的備份,可以進行增量備份。增量備份的時候,需要啟用二進制日志,我們這樣修改配置:
      log-bin=./bin_log/binlog
      也就是在數據目錄下專門創建一個目錄bin_log來保存二進制日志文件。另外,我們希望只記錄我們工作的這個數據庫的二進制日志,而忽略其它的數據庫。配置文件這樣修改:
      binlog-do-db=dbname

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈[未登錄]  回復  更多評論   

    2007-01-16 10:23 by limq
    頂一個,不錯

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-01-18 00:13 by billbai
    辛苦了哈!很好的,我也正想試下這個,有沒有自動生成實體文件的,不用手工寫的

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-01-22 12:56 by 劉金龍
    這個東西沒有什么技術含量,只不過hibernate充分利用了Annotation特性而已,建議好好研究一下標簽,呵呵

    # 8771100  回復  更多評論   

    2007-03-15 17:54 by 000
    0000

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-05-20 15:52 by feifei
    我啥都不說了```````、頂````

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-07-30 16:11 by 小白之家
    這個有點難

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-07-30 16:17 by 小白之家
    能給源碼打個包,look一下嗎?

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-10-17 23:46 by liuxiaoxia_555@163.com
    這樣做的話,在刪除group的時候會出錯啊!能說說怎么能刪除group的同時把user保留!而只是把usergroup表中的數據刪掉?

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-10-18 11:48 by 海邊沫沫
    樓上的說得有道理,我在寫測試代碼的時候只考慮到了添加,而沒有考慮到刪除。至于會不會出錯,我認為不會,多對多關系刪除一方的時候不會刪除另外一方吧。

    就算確實會出錯,我們也可以在Hibernate中使用hql語句或SQL語句來直接操縱數據庫。

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2007-12-15 17:27 by Relax Lin
    太強拉,,,,,,,,,頂

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2008-01-18 17:48 by nicholas85211
    很透徹

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2008-06-28 15:29 by wzz
    測試可以用 user.setRole(roleManager.get( 1 ));。但是在Form頁面中怎么辦呢?form中傳過來的是String類型的數據啊,不是Role型的數據。會報錯的如:
    System Runtime Error:
    Unexpected reflection exception - java.lang.IllegalArgumentException: Cannot invoke com.fh.tms.model.User.setRole - argument type mismatch
    這個問題可以解決嗎?

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2008-08-13 08:09 by 笑笑笑笑笑笑笑
    re: SpringSide開發實戰(四):

    # re: SpringSide開發實戰(四):打通數據持久層的任督二脈  回復  更多評論   

    2008-12-07 19:55 by 虎嘯龍吟
    糾正一下建表的幾個小錯誤,正確的如下:
    create table users(
    id int not null auto_increment primary key ,
    username varchar ( 20 ) not null ,
    password char ( 32 ) not null ,
    monicker varchar ( 30 ) not null ,
    question varchar ( 30 ) not null ,
    answer varchar ( 30 ) not null ,
    email varchar ( 40 ) not null ,
    qq varchar ( 12 ) not null ,
    roleid int not null ,
    score int not null default ' 0 ' ,
    regtime timestamp not null default CURRENT_TIMESTAMP ,
    logintime timestamp not null default ' 2007-01-01 00:00:00 ' ,
    isdeleted varchar ( 2 ) not null default ' 0' ,
    index (username),
    index (monicker)
    );

    create table roles(
    id int not null auto_increment primary key ,
    rolename varchar ( 20 ) not null ,
    privilegesFlag varchar ( 255 ),
    index (rolename)
    );

    create table groups(
    id int not null auto_increment primary key ,
    groupname varchar ( 40 ) not null ,
    creatorid int not null ,
    createtime timestamp not null default CURRENT_TIMESTAMP ,
    isdeleted varchar ( 2 ) not null default ' 0' ,
    index (groupname)
    );

    create table users_groups(
    id int not null auto_increment primary key ,
    userid int not null ,
    groupid int not null ,
    jointime timestamp ,
    status tinyint ,
    index (userid),
    index (groupid)
    );
    主站蜘蛛池模板: 亚洲中文字幕久久精品无码APP | 日韩人妻无码精品久久免费一| 亚洲国产综合久久天堂| 久久精品国产亚洲av品善| 日韩免费a级在线观看| 国产青草亚洲香蕉精品久久| 国产精品久久免费视频| 污污免费在线观看| 又大又硬又爽免费视频| caoporm碰最新免费公开视频| 亚洲美女在线国产| 中国性猛交xxxxx免费看| 亚洲AV无码国产精品色午友在线| 久久成人免费电影| 亚洲国产精品yw在线观看| 最近2019中文字幕mv免费看| 亚洲av无码兔费综合| 免费人成视网站在线观看不卡| 特a级免费高清黄色片| 久久精品国产69国产精品亚洲| 99国产精品免费视频观看| 亚洲一区精品视频在线| 国产成人在线免费观看| fc2免费人成为视频| 无码乱人伦一区二区亚洲| 波多野结衣免费在线| 亚洲AV成人无码网站| 亚洲日韩一页精品发布| 最近免费最新高清中文字幕韩国| 色婷五月综激情亚洲综合| 免费A级毛片无码久久版| 免费观看91视频| 亚洲小说图区综合在线| 亚洲无码高清在线观看| 18禁美女黄网站色大片免费观看| 亚洲色成人网站WWW永久四虎| 国产亚洲精品久久久久秋霞 | 亚洲va久久久噜噜噜久久狠狠| 日本免费人成在线网站| 特级av毛片免费观看| 亚洲理论片在线中文字幕|