spring5x-hibernate5-base

作者: 宇宙小神特别萌 | 来源:发表于2019-12-05 17:44 被阅读0次

    spring5x-hibernate5-base 此模块是从spring5x-base 基础模块扩展过来的
    spring5x-base模块是一个非常干净的spring5.x+springMVC架构
    如果没有搭建spring5x-base模块,请参考 spring5x-base模块搭建

    搭建项目

    基于spring5x-base 基础模块 新增功能:

    • 1、hibernate5 依赖及xml方式配置
    • 2、支持c3p0/druid连接池和mysql/oracle数据库
    • 3、HibernateTemplate 增删改查操作

    1、hibernate5 依赖及xml方式配置


    pom.xml 依赖

            <!--mysql 连接驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.13</version>
            </dependency>
            <!--oracle 连接驱动-->
            <dependency>
                <groupId>com.oracle</groupId>
                <artifactId>ojdbc6</artifactId>
                <version>11.2.0.3</version>
            </dependency>
    
            <!--druid 数据源连接池-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.20</version>
            </dependency>
            <!--hibernate-c3p0 数据源连接池-->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-c3p0</artifactId>
                <version>5.3.10.Final</version>
            </dependency>
    
            <!-- spring的整合hibernate所需的jar:orm,不然会找不到session工厂 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!--apo 解决问题:Failed to introspect Class [org.springframework.aop.aspectj-->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.2</version>
            </dependency>
    
            <!--Hibernate-->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>5.3.7.Final</version>
                <exclusions>
                    <exclusion>
                        <artifactId>classmate</artifactId>
                        <groupId>com.fasterxml</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
    
    

    spring-hibernate5-1.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 数据源配置资源引入 -->
        <!--druid.xml 配置-->
        <import resource="classpath:META-INF/spring/datasource/spring-druid.xml"/>
        <!--c3p0.xml 配置-->
        <!--<import resource="classpath:META-INF/spring/datasource/spring-c3p0.xml"/>-->
    
        <!-- Hibernate 配置  BEGIN -->
    
        <!-- **************配置SessionFactory工厂*************** -->
    
        <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <!--配置数据源-->
            <property name="dataSource" ref="dataSource"/>
    
            <!-- 自动扫描注解:实体类,使用注解@Entity,@Table,@Id等等,不需要hbm.xml -->
    <!--        <property name="packagesToScan">
                <list>
                    <value>com.zja.entity</value>
                </list>
            </property>-->
    
            <!--自动扫描配置:*.hbm.xml,可不使用packagesToScan-->
            <!--<property name="mappingLocations" value="classpath*:com/zja/entity/*.hbm.xml"/>-->
    
            <!--自动扫描配置:*.hbm.xml,可不使用packagesToScan-->
            <property name="mappingLocations">
                <list>
                    <!--添加扫描*.hbm.xml文件的路径-->
                    <value>classpath*:/hbm/*.hbm.xml</value>
                    <!--<value>classpath*:com/zja/entity/*.hbm.xml</value>-->
                </list>
            </property>
    
            <!-- 配置 hibernate-1.cfg.xml 中的信息 -->
            <property name="hibernateProperties">
                <props>
                    <!--数据库方言:Hibernate-5.2.10 之后使用的方言需要升级-->
                    <!--mysql新版本方言:创建表时,引擎engine=MyISAM,优点:查询很快,缺点:不支持事务处理和外键约束-->
                    <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>-->
                    <!--mysql新版本方言:创建表时,引擎engine=InnoDB,优点:支持事务处理和外键约束,缺点:查询很慢,(推荐使用)-->
                    <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>-->
    
                    <!--oracle新版本方言: 支持版本10g和11g-->
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    
                    <!--default_schema:oracle设置用户名:duke,mysql设置数据库名称:test。不推荐使用:默认自动识别-->
                    <!--<prop key="hibernate.default_schema">duke</prop>-->
                    <!--<prop key="hibernate.default_schema">test</prop>-->
    
                    <!--create每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因
                        create-drop加载hibernate时删除表再创建表,退出时删除表结构
                        update加载hibernate自动更新数据库结构,建议禁用update,问题太多(比如第二次运行项目,bug会再次创建表,这时表已存在,报错)
                        validate加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值
                        none不是用此功能(推荐使用) -->
                    <prop key="hibernate.hbm2ddl.auto">none</prop>
                    <!--打印sql语句-->
                    <prop key="hibernate.show_sql">true</prop>
                    <!--sql格式化-->
                    <prop key="hibernate.format_sql">true</prop>
                    <!--禁用 jdbc元数据默认值-->
                    <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
                </props>
            </property>
        </bean>
    
    
        <!-- **************配置事务管理器*************** -->
    
        <!-- 配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    
        <!-- 注解方式(配置事物):通过@Transactional启用事物管理,xml方式的配置会覆盖注解配置 -->
        <!--<tx:annotation-driven transaction-manager="transactionManager" />-->
    
        <!-- XML方式(配置事物):配置事务特性,配置add,delete,update开始的方法,事务传播特性为required -->
        <!-- 配置事务通知属性 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!-- 定义事务传播属性 -->
            <tx:attributes>
                <tx:method name="save*" propagation="REQUIRED"/>
                <tx:method name="merge*" propagation="REQUIRED"/>
                <tx:method name="insert*" propagation="REQUIRED"/>
                <tx:method name="add*" propagation="REQUIRED"/>
                <tx:method name="set*" propagation="REQUIRED"/>
                <tx:method name="new*" propagation="REQUIRED"/>
                <tx:method name="update*" propagation="REQUIRED"/>
                <tx:method name="edit*" propagation="REQUIRED"/>
                <tx:method name="remove*" propagation="REQUIRED"/>
                <tx:method name="delete*" propagation="REQUIRED"/>
                <tx:method name="execute*" propagation="REQUIRED"/>
                <tx:method name="change*" propagation="REQUIRED"/>
                <tx:method name="get*" propagation="REQUIRED" read-only="true"/>
                <tx:method name="find*" propagation="REQUIRED" read-only="true"/>
                <tx:method name="load*" propagation="REQUIRED" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED" read-only="true"/>
            </tx:attributes>
        </tx:advice>
        <!-- 配置那些类的方法进行事务管理,当前com.sy.crm.service包中的子包,类中所有方法需要,还需要参考tx:advice的设置 -->
        <!--dao是原子的数据库操作
            service层可以把多个原子的数据库操作组合
            为了让一个事务里面可以进行多个数据库操作,因此把事务放在service层-->
        <aop:config>
            <aop:pointcut id="allManagerMethod" expression="execution(* com.zja.service.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
        </aop:config>
    
    
        <!-- **************配置hibernateTemplate 操作模板*************** -->
    
        <!-- 配置HibernateTemplate模板操作类,Spring调用 Hibernate 的持久化操作,HibernateTemplate是线程安全的  -->
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
            <property name="sessionFactory" ref="sessionFactory"/>
            <!-- spring与hibernate整合后默认必须在事务下对数据库执行写操作,如果将checkWriteOperations设置为false则没有事务也可写数据库,这样是为了单独测试dao方便 -->
            <!--上面已经配置了事务,注释掉下方代码-->
            <!--<property name="checkWriteOperations" value="false"/>-->
        </bean>
        <!-- Hibernate 配置  END -->
    
    </beans>
    
    

    2、支持c3p0/druid连接池和mysql/oracle数据库

    jdbc.properties

    # mysql 数据库配置:
    #新的驱动driverClassName
    mysql.jdbc.driverClassName=com.mysql.cj.jdbc.Driver
    mysql.jdbc.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    mysql.jdbc.username=root
    mysql.jdbc.password=123456
    mysql.jdbc.validationQuery=select 'x'
    
    
    # oracle 数据库配置:
    oracle.jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
    oracle.jdbc.url=jdbc:oracle:thin:@127.0.0.1/orcl
    oracle.jdbc.username=duke
    oracle.jdbc.password=duke
    oracle.jdbc.validationQuery=select 'x' from dual
    
    

    spring-druid.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
    
        <!--指定jdbc配置文件的位置-->
        <context:property-placeholder location="classpath:properties/jdbc.properties" ignore-unresolvable="true"/>
    
        <!--配置 druid 数据源 关于更多的配置项 可以参考官方文档 <a href="https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8" > -->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    
            <!-- 基本属性 url、user、password ,driverClassName默认自动识别-->
            <!--配置mysql -->
            <!--<property name="url" value="${mysql.jdbc.url}"/>
            <property name="username" value="${mysql.jdbc.username}"/>
            <property name="password" value="${mysql.jdbc.password}"/>
            <property name="validationQuery" value="${mysql.jdbc.validationQuery}"/>
            <property name="driverClassName" value="${mysql.jdbc.driverClassName}"/>-->
    
            <!--配置oracle -->
            <property name="url" value="${oracle.jdbc.url}"/>
            <property name="username" value="${oracle.jdbc.username}"/>
            <property name="password" value="${oracle.jdbc.password}"/>
            <property name="validationQuery" value="${oracle.jdbc.validationQuery}"/>
            <property name="driverClassName" value="${oracle.jdbc.driverClassName}"/>
    
            <!--validationQuery属性说明:用来检测连接是否有效的 sql,要求是一个查询语句,常用 select 'x'。
                但是在 oracle 数据库下需要写成 select 'x' from dual 不然实例化数据源的时候就会失败,
                这是由于 oracle 和 mysql 语法间的差异造成的-->
    
            <!--*****druid 公共属性配置*****-->
            <!-- 初始化连接大小 -->
            <property name="initialSize" value="10"/>
            <!-- 连接池最小空闲 -->
            <property name="minIdle" value="10"/>
            <!-- 连接池最大使用连接数量 -->
            <property name="maxActive" value="200"/>
    
            <!-- 配置获取连接等待超时的时间 -->
            <property name="maxWait" value="60000"/>
    
            <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
            <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    
            <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
            <property name="minEvictableIdleTimeMillis" value="600000"/>
            <!-- 配置一个连接在池中最大生存的时间,单位是毫秒 -->
            <property name="maxEvictableIdleTimeMillis" value="900000"/>
    
            <!--建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,
            如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。-->
            <property name="testWhileIdle" value="true"/>
            <!--申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。-->
            <property name="testOnBorrow" value="false"/>
            <!--归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。-->
            <property name="testOnReturn" value="false"/>
    
            <!--连接池中的 minIdle 数量以内的连接,空闲时间超过 minEvictableIdleTimeMillis,则会执行 keepAlive 操作。-->
            <property name="keepAlive" value="true"/>
            <property name="phyMaxUseCount" value="100000"/>
    
            <!-- 配置连接池中,创建连接时,采用异步|同步方式来进行创建,默认是:异步 -->
            <property name="asyncInit" value="true" />
    
            <!-- 配置监控统计拦截的 filters Druid 连接池的监控信息主要是通过 StatFilter 采集的,
            采集的信息非常全面,包括 SQL 执行、并发、慢查、执行时间区间分布等-->
            <!-- 配置额外的扩展插件:stat 代表开启监控程序,wall 代表开启防SQL注入功能 -->
            <property name="filters" value="stat,wall"/>
        </bean>
    
    </beans>
    
    

    spring-c3p0.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--指定配置文件的位置-->
        <context:property-placeholder location="classpath:properties/jdbc.properties" ignore-unresolvable="true"/>
    
        <!-- 配置 C3P0 数据源 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
            <!--配置mysql -->
            <property name="driverClass" value="${mysql.jdbc.driverClassName}" />
            <property name="jdbcUrl" value="${mysql.jdbc.url}" />
            <property name="user" value="${mysql.jdbc.username}" />
            <property name="password" value="${mysql.jdbc.password}" />
    
            <!--配置oracle -->
            <!--<property name="driverClass" value="${oracle.jdbc.driverClassName}" />
            <property name="jdbcUrl" value="${oracle.jdbc.url}" />
            <property name="user" value="${oracle.jdbc.username}" />
            <property name="password" value="${oracle.jdbc.password}" />-->
    
            <!--c3p0公共属性配置-->
            <!-- 数据库连接池中的最大的数据库连接数,建议在开发环境中设置小一点,够用即可 -->
            <property name="maxPoolSize" value="25"/>
            <!-- 数据库连接池中的最小的数据库连接数 -->
            <property name="minPoolSize" value="5"/>
            <!-- 如果池中数据连接不够时一次增长多少个 -->
            <property name="acquireIncrement" value="5"/>
            <!-- 初始化数据库连接池时连接的数量 -->
            <property name="initialPoolSize" value="20"/>
    
        </bean>
    
    </beans>
    
    

    3、HibernateTemplate 增删改查操作

    UserEntity.java

    @Data
    @Entity
    @Table(name = "userentity")
    @ApiModel("用户信息实体类")
    public class UserEntity implements Serializable {
    
        @ApiModelProperty(value = "默认:mysql自增,oracle序列")
        @Id
        @Column(name = "id", nullable = false)
        private Integer id;
        @ApiModelProperty("用户名")
        @Basic(fetch =FetchType.EAGER,optional = false) //急加载,属性是否允许为null
        @Column(name = "username", nullable = false, length = 225)
        private String userName;
        @ApiModelProperty("年龄")
        @Column(name = "age", nullable = true)
        private Integer age;
        @ApiModelProperty("不传值,后台创建时间")
        @Column(name = "createtime", nullable = true)
        private Date createTime;
        @ApiModelProperty("不传值,后台创建时间")
        @Column(name = "updatetime", nullable = true)
        private Date updateTime;
    }
    
    

    resources/hbm/UserEntity.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>
        <class name="com.zja.entity.UserEntity" table="userentity">
            <id name="id" column="id" type="int">
                <!--<column name="id" sql-type="int"/>-->
                <!--在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库,首次从数据库取主键最大的值-->
                <generator class="increment" />
                <!--根据数据库自动选择identity、hilo、sequence其中一种,例如MySQL使用identity,Oracle使用sequence(默认序列查找hibernate_sequence序列),使用自定义序列时需加入参数sequence_name-->
                <!--<generator class="native">
                    <param name="sequence_name">SEQ_MY_HIBERNATE</param>
                </generator>-->
                <!--需要数据库支持sequence,例如oralce、PostgerSQL等,不支持 mysql(可以使用identity)-->
                <!--<generator class="sequence">
                    &lt;!&ndash;SEQ_MY_HIBERNATE 是自定义创建的序列,指定sequence的名称&ndash;&gt;
                    <param name="sequence_name">SEQ_MY_HIBERNATE</param>
                </generator>-->
            </id>
            <property name="userName">
                <!--不可为null-->
                <column name="username" sql-type="varchar(225)" length="225" not-null="true"/>
            </property>
            <property name="age">
                <!--可为null-->
                <column name="age" sql-type="int" not-null="false"/>
            </property>
            <property name="createTime">
                <column name="createtime" sql-type="date" not-null="false"/>
            </property>
            <property name="updateTime">
                <column name="updatetime" sql-type="timestamp" not-null="false"/>
            </property>
        </class>
    </hibernate-mapping>
    
    

    HibernateTemplate 使用

    package com.zja.service.Impl;
    
    import com.zja.entity.UserEntity;
    import com.zja.service.UserService;
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.criterion.DetachedCriteria;
    import org.hibernate.criterion.Order;
    import org.hibernate.criterion.Restrictions;
    import org.hibernate.query.NativeQuery;
    import org.hibernate.query.Query;
    import org.springframework.orm.hibernate5.HibernateCallback;
    import org.springframework.orm.hibernate5.HibernateTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author ZhengJa
     * @description
     * @data 2019/11/19
     */
    @Service("userServiceImpl")
    public class UserServiceImpl implements UserService {
    
        @Resource
        private HibernateTemplate hibernateTemplate;
    
    
        /*********** save/merge存数据 *************/
    
        /**
         * save保存-成功
         *
         * @param userEntity
         */
        @Override
        public Object saveEntity(UserEntity userEntity) {
            userEntity.setCreateTime(new Date());
            return hibernateTemplate.save(userEntity);
        }
    
        /**
         * save保存-成功
         *
         * @param userEntity
         */
        @Override
        public Object saveEntity2(UserEntity userEntity) {
            userEntity.setCreateTime(new Date());
            return hibernateTemplate.save("userEntity", userEntity);
        }
    
        /**
         * merge保存-成功 :存在则更新,不存在则保存
         * 使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到
         * 一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态
         *
         * @param userEntity 实体类
         */
        @Override
        public UserEntity mergeEntity(UserEntity userEntity) {
            userEntity.setCreateTime(new Date());
            return hibernateTemplate.merge(userEntity);
        }
    
        /**
         * merge保存-成功 :存在则更新,不存在则保存
         *
         * @param userEntity 实体类
         */
        @Override
        public UserEntity mergeEntity2(UserEntity userEntity) {
            userEntity.setCreateTime(new Date());
            return hibernateTemplate.merge("userEntity", userEntity);
        }
    
    
        /*********** get/load存取单条数据 *************/
        //get和load的根本区别:
        // hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在 使用过程中发现了问题,就抛异常;
        // 对于get方法,hibernate一定要获取到真实的数据,否则返回null
    
        /**
         * 根据id获取用户信息-成功
         * 查询数据不存在,返回null,推荐使用, 不存在延迟加载问题,不采用lazy机制的
         *
         * @param id
         */
        @Override
        public UserEntity getEntity(Integer id) {
            return hibernateTemplate.get(UserEntity.class, id);
        }
    
        /**
         * load查询单条数据,查询数据不存在,报异常,不推荐使用,存在延迟加载问题-失败
         *
         * @param id
         */
        @Override
        public UserEntity loadEntity(Integer id) {
            return hibernateTemplate.load(UserEntity.class, id);
        }
    
        /**
         * loadAll查询所有用户信息-成功
         *
         * @param
         */
        @Override
        public List<UserEntity> getListEntity() {
            return hibernateTemplate.loadAll(UserEntity.class);
        }
    
        /**
         * 根据id查询-失败
         *
         * @param id
         */
        @Override
        public UserEntity getEntityName(Integer id) {
            Object userEntity = hibernateTemplate.get("userEntity", id);
            System.out.println("userEntity: " + userEntity);
            return (UserEntity) hibernateTemplate.get("userEntity", id);
        }
    
        /**
         * 分页查询-不推荐用-成功
         */
        @Override
        public List<UserEntity> getPageByConditions() {
            //hibernateTemplate单例,分页会有问题,执行一次分页后,其它的所有查询都是分页后效果
            hibernateTemplate.setMaxResults(5);
            List<UserEntity> loadAll = hibernateTemplate.loadAll(UserEntity.class);
            hibernateTemplate.setMaxResults(0);
            return loadAll;
        }
    
        /*********** 更新 *************/
    
        /**
         * 更新-成功
         *
         * @param userEntity
         */
        @Override
        public void updateEntity(UserEntity userEntity) {
            hibernateTemplate.update(userEntity);
        }
    
        /**
         * 保存或更新:id不存在则保存,存在则更新-成功
         *
         * @param userEntity
         */
        @Override
        public void saveOrUpdate(UserEntity userEntity) {
            hibernateTemplate.saveOrUpdate(userEntity);
        }
    
        /*********** 删除 *************/
    
        /**
         * 删除单条数据-成功
         *
         * @param id
         */
        @Override
        public void deleteByEntity(Integer id) {
            hibernateTemplate.delete(getEntity(id));
        }
    
        /**
         * 删除全部数据-成功
         *
         * @param
         */
        @Override
        public void deleteAll() {
            List<UserEntity> userEntityList = findByCriteria();
            hibernateTemplate.deleteAll(userEntityList);
        }
    
    
        /*********** hibernateTemplate执行原生sql脚本 *************/
    
        /**
         * HiberateTemplate提供的方法不能满足要求时才使用execute方法 执行sql -成功
         */
        @Override
        public Object execute() {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    //创建空表mysql_ok
                    session.createSQLQuery(
                            "DROP TABLE IF EXISTS `mysql_ok`;")
                            .executeUpdate();
                    int i = session.createSQLQuery(
                            "CREATE TABLE `mysql_ok` (`ok`  varchar(3) NOT NULL ,PRIMARY KEY (`ok`));")
                            .executeUpdate();
                    System.out.println("成功创建空表mysql_ok :i=" + i);
                    return i;
                }
            });
            return o;
        }
    
        /**
         * 保存实体类-成功
         * @param userEntity
         */
        @Override
        public Object executeSaveUserEntity(UserEntity userEntity) {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    Serializable save = session.save(userEntity);
                    System.out.println("id=" + save);
                    return save;
                }
            });
            return o;
        }
    
    
    
        //1. HQL查询
        /*********** HQL查询 面向对象查询数据 *************/
    
        /**
         * 通过Hql执行获取所有用户
         */
        @Override
        public Object getAllUserEntityByHql() {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    // 这里UserEntity是对象名,不是数据库表名
                    String hql ="from UserEntity";
                    Query<UserEntity> query = session.createQuery(hql);
                    List<UserEntity> userEntityList = query.list();
                    return userEntityList;
                }
            });
            return o;
        }
    
        /**
         * 通过Hql执行获取唯一的用户
         */
        @Override
        public Object getUserEntityByHql(Integer id) {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    // 这里UserEntity是对象名,不是数据库表名,id也不是数据库字段名称
                    String hql ="from UserEntity where id ="+id;
                    //推荐使用,易读
                    Query<UserEntity> query = session.createQuery(hql);
                    // 知道返回结果是唯一的,使用uniqueResult
                    UserEntity userEntity = query.uniqueResult();
                    return userEntity;
                }
            });
            return o;
        }
    
        @Override
        public Object getNameByHQL() {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    // 这里UserEntity是对象名,不是数据库表名,username也不是数据库字段名称
                    String hql ="select userName from UserEntity";
                    Query<UserEntity> query = session.createQuery(hql);
                    //集合中直接存放着name属性,不是对象
                    List<UserEntity> userEntityList = query.list();
                    //结果: ["小明","小刘","小王","明月","秦时","阿里"]
                    return userEntityList;
                }
            });
            return o;
        }
    
    
        //2.原生SQL查询
        /*********** 原生SQL查询数据 *************/
    
        /**
         * 通过Sql执行获取所有用户
         */
        @Override
        public Object executeGetUserEntityBySql() {
            Object o = this.hibernateTemplate.execute(new HibernateCallback<Object>() {
                @Override
                public Object doInHibernate(Session session) throws HibernateException {
                    // 这里UserEntity是对象名,不是数据库表名
                    String sql ="select * from userentity";
                    // 创建一个接收结果集的SQLQuery对象
                    NativeQuery sqlQuery = session.createSQLQuery(sql);
                    // 通过addEntity,来绑定到实体
                    List<UserEntity> userEntityList = sqlQuery.addEntity(UserEntity.class).list();
    
                    return userEntityList;
                }
            });
            return o;
        }
    
    
        /*********** findByExample查询数据 *************/
    
        /**
         * 根据条件查询-成功
         */
        @Override
        public List<UserEntity> findByExample() {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserName("小刘");
            userEntity.setAge(20);
            //必须 符合的条件但是这 "username=小刘 and age=20" 两个条件时并列的(象当于sql中的and)
            return hibernateTemplate.findByExample(userEntity);
        }
    
        /**
         * 根据调条件查询并分页-成功
         *
         * @param firstResult 页码 从0开始
         * @param maxResults  每页显示多少条数据,等于0或负数则查询所有
         */
        @Override
        public List<UserEntity> findByExample(int firstResult, int maxResults) {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserName("小刘");
            userEntity.setAge(20);
            return hibernateTemplate.findByExample(userEntity, firstResult, maxResults);
        }
    
        //3.QBC(Query By Criteria)命名查询 面向对象查询
        /*********** findByExample查询数据 *************/
    
        /**
         * 查询所有数据 -成功
         */
        @Override
        public List<UserEntity> findByCriteria() {
            //DetachedCriteria:离线条件查询对象,该对象的创建不需要session对象,替代了Criteria查询
            DetachedCriteria criteria = DetachedCriteria.forClass(UserEntity.class);
            return (List<UserEntity>) hibernateTemplate.findByCriteria(criteria);
        }
    
        /**
         * 分页查询-成功
         *
         * @param firstResult 页码 从0开始
         * @param maxResults  每页显示多少条数据,等于0或负数则查询所有
         */
        @Override
        public List<UserEntity> findPageByCriteria(int firstResult, int maxResults) {
            //firstResult 第几页,maxResults每页显示多少条
            DetachedCriteria criteria = DetachedCriteria.forClass(UserEntity.class);
            return (List<UserEntity>) hibernateTemplate.findByCriteria(criteria, firstResult, maxResults);
        }
    
        /**
         * 根据属性名称和属性值查询-成功
         *
         * @param propertyName  类的属性名称
         * @param propertyValue 属性值
         * @param firstResult   页码 从0开始
         * @param maxResults    每页显示多少条数据,等于0或负数则查询所有
         */
        @Override
        public List<UserEntity> findByCriteria(String propertyName, Object propertyValue, int firstResult, int maxResults) {
            DetachedCriteria criteria = DetachedCriteria.forClass(UserEntity.class);
            //根据属性名称和属性的value值查询
            criteria.add(Restrictions.eq(propertyName, propertyValue));
            return (List<UserEntity>) hibernateTemplate.findByCriteria(criteria, firstResult, maxResults);
        }
    
        /**
         * 模糊查询按年龄区间和大小排序-成功
         *
         * @param low  低
         * @param high 高  low --> high 从低到高,顺序一定要正确,否则查询会有问题,或查询不到数据
         */
        @Override
        public List<UserEntity> findByCriteria(int low, int high) {
            //
            DetachedCriteria criteria = DetachedCriteria.forClass(UserEntity.class);
            //根据属性名称和属性的value值查询
            criteria.add(Restrictions.like("userName", "小%"));
            criteria.add(Restrictions.between("age", low, high));
            //根据属性名称进行排序
            criteria.addOrder(Order.desc("age"));
            return (List<UserEntity>) hibernateTemplate.findByCriteria(criteria);
        }
    
    
    }
    
    

    github 地址:

    博客地址:

    相关文章

      网友评论

        本文标题:spring5x-hibernate5-base

        本文链接:https://www.haomeiwen.com/subject/uckjgctx.html