Session的save()方法 .

本文详细介绍了Hibernate中Session的save()方法如何将临时对象转变为持久化对象,并探讨了其内部实现机制,包括OID的设置、insert语句的执行时机等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Session的save()方法使一个临时对象转变为持久化对象。例如以下代码保存一个Customer对象:

        Customer customer = new Customer();

        customer.setId(new Long(9)); // 为Customer临时对象设置OID是无效的

        customer.setName("Tom");

        Session session = sessionFactory.openSession();

        Transaction tx = session.beginTransaction();

        session.save(customer);

        session.close();

    Session的save()方法完成以下的操作:

    (1)把Customer对象加入到缓存中,使它变为持久化对象。

    (2)选用映射文件指定的标识符生成器为持久化对象分配惟一的OID。Customer.hbm.xml文件中<id>元素的<generator>子元素指定标识符生成器:

        <id name="id" column="ID">

            <generator class="increment"/>

        </id>

    以上程序试图通过setId()方法为Customer临时对象设置OID是无效的。假如起初CUSTOMERS表中没有记录,那么执行完save()方法后,Customer对象的ID为1。如果希望由程序来为Customer对象指定OID,可以调用save()的另一个重载方法:

        save(customer, new Long(9));

    以上save()方法的第二参数显示指定Customer对象的OID。这种形式的save()方法不推荐使用,尤其在使用代理主键的场合,不应该由程序为持久化对象指定OID。

    (3)计划执行一个insert语句,把Customer对象当前的属性值组装到insert语句中:

        insert into CUSTOMERS(ID, NAME, ......) values(1, 'Tom', ......);

    值得注意的是,save()方法并不立即执行SQL insert语句。只有当Session清理缓存时,才会执行SQL insert语句。如果在save()方法之后,又修改了持久化对象的属性,这会使得Session在清理缓存时,额外执行SQL update语句。以下两段代码尽管都能完成相同的功能,但是左边代码仅执行一条SQL insert语句,而右边代码执行一条SQL insert和一条SQL update语句。左边代码减少了操作数据库的次数,具有更好的运行性能。

        Customer customer = new Customer();         Customer customer = new Customer();

        // 先设置Customer对象的属性,再保存它       session.save(customer);

        customer.setName("Tom");                    // 先保存Customer对象,再修改它的属性

        session.save(customer);                     customer.setName("Tom");

        transaction.commit();                       transaction.commit();

    Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系。当Customer对象处于持久化状态时,不允许程序随意修改它的OID,例如:

        Customer customer = new Customer();

        session.save(customer);

        customer.setId(new Long(100)); // 抛出HibernateException

        transaction.commit();

    以上代码会导致Session在清理缓存时抛出异常。

 


无论Java对象处于临时状态、持久化状态还是游离状态,应用程序都不应该修改它的OID。因此,比较安全的做法是,在定义持久化类时,把它的setId()方法高为private类型,禁止外部程序访问该方法。


 

    Session的save()方法是用来持久化一个临时对象的。在应用程序中不应该把持久化对象或游离对象传给save()方法。例如以下代码两次调用了Session的save()方法,第二次传给save()方法的Customer对角处于持久化状态,这步操作其它是多余的:

        Customer customer = new Customer();

        session.save(customer);

        customer.setName("Tom");

        session.save(customer); // 这步操作是多余的

       transaction.commit();

    在例如以下代码把Customer游离对象传给session2的save()方法,session2会把它当做临时对象处理,再次向数据库中插入一条Customer记录:

        Customer customer = new Customer();

        customer.setName("Tom");

        Session session1 = sessionFactory.openSession();

        Transaction tx1 = session1.beginTransaction();

        session1.save(customer); // 此时Customer对象的ID变为1

        tx1.commit();

        session1.close(); // 此时Customer对象变为游离对象

        Session session2 = sessionFactory.openSession();

        Transaction tx2 = session2.beginTransaction();

        session2.save(cutomer); // 此时Customer对象的ID变为2

        tx2.commit();

        session2.close();

    尽管以上程序代码能正常运行,但是会导致CUSTOMERS表中有两条代表相同业务实体的记录,因此不符合业务逻辑。



http://blog.youkuaiyun.com/xiancaifu/article/details/6618424

<think>嗯,用户想了解如何正确配置PHP的open_basedir和session.save_path参数,需要示例和文件路径限制。首先,我得回忆一下这两个配置项的作用和常见设置方法。 open_basedir是用来限制PHP脚本可以访问的目录,防止跨目录访问,提升安全性。应该配置在php.ini文件中,或者通过.htaccess或ini_set()在运行时设置。需要指定允许的目录列表,多个目录用分号分隔。比如,如果用户有一个网站根目录是/www/htdocs,那么open_basedir应该设置为/www/htdocs:/tmp,这样PHP只能访问这两个目录下的文件。要注意路径的正确格式,避免尾部斜杠,否则可能出错。 然后是session.save_path,这个参数设置session文件的保存位置。默认情况下,PHP可能会使用系统的临时目录,但为了安全和权限管理,最好自定义一个目录。例如,设置为/var/lib/php/session,并确保该目录存在且PHP进程有读写权限。同时,这个目录也需要包含在open_basedir的设置中,否则session无法正常保存。权限方面,通常设置为1730,所有者是www-data或对应的Web服务器用户,这样其他用户无法访问,避免安全风险。 用户可能遇到的问题包括配置后出现权限错误,或者路径设置不正确导致功能失效。比如,如果session.save_path没有包含在open_basedir里,session会无法写入,这时候需要检查路径是否被允许。另外,配置多个目录时要注意分隔符的正确使用,Windows和Linux的分隔符不同,用户可能混淆。 还需要考虑虚拟主机的情况,每个站点可能需要独立的open_basedir和session目录。例如,在Apache的虚拟主机配置中,可以通过php_admin_value来分别设置,这样不同站点的配置不会互相干扰。同时,确保每个session目录的权限正确,防止跨站点的session数据泄露。 用户提供的引用中有提到session.use_only_cookies和session.cookie_domain等配置,这些和session安全相关,但当前问题主要关注路径配置。不过可以提醒用户,除了设置save_path,还应该启用use_only_cookies来增强安全性,避免session id通过URL传递。 最后,需要给出具体的示例配置,帮助用户直观理解如何修改php.ini或虚拟主机文件。比如,在php.ini中设置open_basedir = /www/htdocs:/tmp,session.save_path = /var/lib/php/session,并确保目录权限正确。同时,提供验证配置是否生效的方法,如创建测试脚本输出相关配置值,或者检查phpinfo()的输出。</think>### PHP的open_basedir和session.save_path配置方法 #### 一、open_basedir配置 **作用**:限制PHP脚本可访问的文件路径范围,防止跨目录访问攻击[^3] **配置方法**: 1. 在`php.ini`中全局配置: ```ini open_basedir = /www/htdocs:/tmp ``` 2. 在虚拟主机中单独配置(Apache示例): ```apache <VirtualHost *:80> php_admin_value open_basedir "/www/htdocs:/tmp" </VirtualHost> ``` 3. 通过`.htaccess`文件配置: ```php php_value open_basedir "/www/htdocs:/tmp" ``` **示例说明**: - `/www/htdocs`对应MVC框架入口文件所在目录[^2] - `/tmp`用于存放临时文件 - 多个路径用英文冒号分隔(Windows系统用分号) #### 二、session.save_path配置 **作用**:指定session文件存储位置,防止默认临时目录权限问题 **配置方法**: ```ini ; php.ini配置 session.save_path = "/var/lib/php/session" ``` **目录要求**: 1. 创建目录并设置权限: ```bash mkdir -p /var/lib/php/session chown www-data:www-data /var/lib/php/session chmod 1730 /var/lib/php/session ``` 2. 需包含在open_basedir范围内: ```ini open_basedir = /www/htdocs:/tmp:/var/lib/php/session ``` **验证配置**: 创建测试文件`info.php`: ```php <?php ini_set('display_errors', 1); session_start(); echo ini_get('session.save_path'); ``` #### 三、典型错误处理 1. **权限拒绝错误**: ```log Warning: session_start(): open_basedir restriction in effect ``` 解决方法:检查`session.save_path`是否在`open_basedir`允许路径中 2. **目录不存在错误**: ```log Warning: session_start(): Session save path cannot be accessed ``` 解决方法:手动创建目录并设置正确权限 3. **路径格式错误**: ```log open_basedir cannot be set due to syntax error ``` 解决方法:检查路径分隔符和特殊字符 #### 四、安全增强建议 1. 配合`session.use_only_cookies = 1`使用,禁止URL传递session ID 2. 定期清理过期session文件: ```bash find /var/lib/php/session -type f -mtime +7 -delete ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值