Orm数据库持久化框架

Orm数据库持久化框架

一、概述

 1、注解描述

注解有两种类型,一种是标识类的做用、一种是标识实体类的字段

 

名称

类型

参数

描述

Dao

类注解

org.smile.commons.ann

name

用于注入到IOC容器的名称

[可选]

默认为类名前一个字母小写

Dao注解用于标记是DAO数据库操作的接口

Table

类注解

org.smile.commons.ann

tableName 必选 数据库表名

Table 注解用于标记与数据库表映射的实体类

Mapper

类注解

org.smile.commons.ann

name [可选] 映射的名称 默认为类的全名

注解用于标记与数据库映射的查询类可不与数据库字段数相同,可是多个表的字段,查询的别名

Id

成员变量注解

org.smile.commons.ann

column [可选] 数据库的表字段名 默认属性变量名

 

uuid [可选] 是否是需要自动创建的uuid主键

 

autoincrement [可选] 是否是自动增加的主键

主键字段

Property

成员变量注解

org.smile.commons.ann

column [可选] 数据库的表字段名 默认属性变量名

 

store [可选] 是否是需要是数据库存贮的字段

 

autoincrement [可选] 是否是自动增长的

属性字段

2、使用示例

此框架使用的方式与mybatis和hibernate等框架主体设计非常相相似,如果对mybatis和hibernate框架有一定的了解,则可以直接上手开发

实体类代码

@Table(tableName="dgb01")

public class TGroupBadBase{

 

    /**基础信息序号 自动生成*/

    @Id(column="dgba01",autoincrement=true)

    protected  long id;

    /**发生地区*/

    @Property(column="dgba02")

    protected  String eventArea;

}

 

Dao 接口

@Dao

public interface IGroupBadDao extends BaseDAO{

    /**

     * @param query

     * @return

     */

    public List<TGroupBadBase> queryGroupBadList(BadQuery query);

 

   

}

Xml 配置  

在Dao接口类包下创建一个文件名与类名一样的xml文件

<mapper sqlType="osql">

    <select id="queryGroupBadList">

       <![CDATA[

           select * from TGroupBadBase where 1=1 

           <#if startDate?? && startDate!=''>

              and firstEventDate>=:startDate

           </#if>

           <#if endDate?? && endDate!=''>

              and firstEventDate<='${endDate} 23:59:59'

           </#if>

          

       ]]>

    </select>

</mapper>

Service 调用代码

@Service

public class GroupBadService {

    @Resource

    private IGroupBadDao iGroupBadDao;

   

 

    @Transactional(propagation = Propagation.REQUIRED)

    public List<TGroupBadBase> queryGroupBadList(BadQuery query) {

       return iGroupBadDao.queryGroupBadList(query);

    }

}

3、Spring中的配置使用

Orm框架是一个可以和spring完美整合的一个框架,只需要在spring的配置文件中做一此配置就可以很好的自定义出一套适合自己的开发方案

3.1、基本的daoSupport使用

DaoSupport是一个兼容Spring框架的org.smile.orm.base.BaseDAO接口的实现,此类可以在Service层直接引用也可以在Dao接口中直接继承。使用时只需要注入到IOC容器中即可。

 

可配置的两个属性:

whereSqlParser :用于解析where语句的工具 

                   参数需要实现 org.smile.orm.base.impl.WhereSqlParser接口。

                   在框架中已经有两种实现:

                   1)org.smile.orm.base.impl. BaseWhereSqlParser

                     普通sql语句的实现 语句里只能使用数据库字段做为过滤条件

                      如:iGroupBadDao.delete(TGroupBadDrug.class, "event_id=?",model.getId() );

                   2) org.smile.orm.base.impl.OrmWhereSqlParser

                            可以支持实体类的属性和数据库字段两种方式过滤条件

                      如:iGroupBadDao.delete(TGroupBadDrug.class, "event_id=?",model.getId() );

                                     iGroupBadDao.delete(TGroupBadDrug.class, "eventId=?",model.getId() );

                                     两种方法用可以达到过滤的效果

dataSource:用于数据源的配置

 

<bean id="ormDaoSupport" class="org.smile.orm.spring.DaoSupport">

        <property name="whereSqlParser">

            <bean class="org.smile.orm.base.impl.OrmWhereSqlParser"></bean>

        </property>

        <property name="dataSource" ref="dataSource"></property>

</bean>

3.2 OrmSessionFactory的使用

 框架提供了一个可以在Spring中偡的OrmSessionFactory实现,只需要配置到IOC容器中即可以使用ORM的方法快速对数据库操作。org.smile.orm.spring.SpringOrmSessionFactoryBean提供了丰富的配置属性来定制自己的开发框架。

3.2.1 例子引导

首一个个配置的例子来详细说明一下org.smile.orm.spring.SpringOrmSessionFactoryBean的使用。

<bean id="ormSessionFactory" class="org.smile.orm.spring.SpringOrmSessionFactoryBean">

        <property name="dataSource" ref="dataSource"></property>

        <property name="packageString">

            <list>

                <value>com.pharmacist.orm,com.pharmacist.dao</value>

                <value>com.pharmacist.report.dao</value>

                <value>com.pharmacist.model</value>

            </list>

        </property>

        <property name="baseTarget" ref="ormDaoSupport"></property>

        <property name="interceptors" >

            <list>

                <bean class="org.smile.orm.plugin.PageQueryInterceptor"></bean>

                <bean class="org.smile.orm.plugin.OrderbyInterceptor"></bean>

                <bean class="org.smile.orm.plugin.TopInterceptor"></bean>

            </list>

        </property>

        <property name="mapperFlagHandler" >

            <bean class="org.smile.orm.mapper.flag.MultipleMapperFlagHandler">

                <property name="handlers">

                    <list>

                        <bean class="org.smile.orm.mapper.flag.SmileMapperFlagHandler"/>

                        <bean class="org.smile.orm.mapper.flag.HibernateMapperFlagHandler"/>

                    </list>

                </property>

            </bean>

        </property>

        <property name="sqlConverters">

            <map>

                <entry key="sql" value="org.smile.orm.executor.sql.NamedBaseSqlConverter"></entry>

                <entry key="osql" value="org.smile.orm.executor.sql.NamedOrmSqlConverter"></entry>

            </map>

        </property>

        <property name="tableMapperClass" value="org.smile.orm.mapper.NamedOrmTableMapper"></property>

        <property name="autoReLoad" value="true"></property>

        <property name="reloadXmlDelay" value="30"></property>

    </bean>

由上面的例子可以看出个大概主要有以下几个属性:

数据源配置:配置数据库操作的数据源

ORM框架扫描的包路径:包括Mapper Table Dao 几个注解的扫描

默认的Dao扩展方法实现目标:是在DAO接口中定义了方法但又没有xml和注解配置方法实现语名的时候                                                     就会用到扩展的目标来实现此方法,对于每一个Dao 接口都可以在xml中                                                    配置他的扩展目标,如果没有配置就会使用ormSessionFactory的                                                              basetarget属性来实现。

拦截器配置:配置的拦截器可以用来实现对框架中的原有实现进行代理,以使用自己的扩展

当然框架中也有一些默认实现的拦截器可用来配置自定义出适合自己的框架,自定义的拦截器需要实现org.smile.plugin.Interceptor接口

映射注解加载处理类:对映射实体类的注解与数据库对应的方式加载的实现,需实现org.smile.orm.mapper.flag.MapperFlagHandler接口,框架提供了两种实现方式和一种多方式实现

Sql语句转换方式配置:配置对Sql处理的实现方式

表映射生成SQL语句配置:配置对实体类生成Sql语句的方式

是否自动重加载Dao xml文件:是否自动定时间隔对xml文件重加载

自动重加载Dal xml文件的时间:自动扫描xml加载的时单间隔单位秒

3.2.2 配置属性

属性名称

类型

是否

必选

可配置值

默认值

详情

dataSource

javax.sql.DataSource

 

 

操作的数据库

packageString

java.util.List

需要扫描的包名

 

每一个list的元素都可以是多个包名的字符串,可以用;和,分开

baseTarget

实现了Dao接口部分父接口的实现类

 

 

用于配置dao接口的扩展实现

interceptors

java.util.List

一个拦截器的列表

 

第一个拦截器需实现 org.smile.plugin.Interceptor接口

 

mapperFlagHandler

org.smile.orm.mapper.flag.MapperFlagHandler

配置实例类加载方式

org.smile.orm.mapper.flag.SmileMapperFlagHandler

此配置值是会加载以@Table标记的类 以@Proerpty标记的属性为字段 @Id标记主键

可以同时支持多种加载方式org.smile.orm.mapper.flag.MultipleMapperFlagHandler

如上例所示 就是支持两种方式

sqlConverters

java.util.Map

配置sql语句转换的方式

sql:OrmSqlConverter

osql:BaseSqlConverter

可以在dao接口的xml文件中指定多种语句类型 只要在此配置转换器即可

tableMapperClass

org.smile.orm.mapper.OrmTableMapper

生成sql 方式

org.smile.orm.mapper. BoundOrmTableMapper

有几种方式:

以%{propertyName}占位

以:propertyName占位

4、可选择的配置

4.1 tableMapperClass

   框架中预设了两种实现类:

4.1.1 第一种

org.smile.orm.mapper.NamedOrmTableMapper

        

使用:propertyName占位生成Sql语句

 

4.1.2 第二种

org.smile.orm.mapper.BoundOrmTableMapper

 

使用%{propertyName}占位生成Sql语句

 

4.2 sqlConverters

具有四种实现,分为两类:

 

只支持普通Sql的 :

1)  org.smile.orm.executor.sql.BaseSqlConverter 

可以处理使用%{propertyName}方式占位的sql

2) org.smile.orm.executor.sql.NamedBaseSqlConverter

 可以处理使用:propertyName方式占位的sql

3) org.smile.orm.executor.sql .OrmSqlConverter

  可以处理以%{propertyName}方式占位的带实体Table类做为字段和表名的sql语句

4) org.smile.orm.executor.sql .NamedOrmSqlConverter

  可以处理以:propertyName方式占位的带实体Table类做为字段和表名的sql语句

 

5 Sql占位符

对于sql的占位符是解析sql语句的关键所在,所以必须要正解配置

 

如果不对tableMapperClass、sqlConverters 两个属性进行配置,系统默认的是以%{propertyName}做为占位符的。

5.1 方式统一

配置时必须要做到tableMapperClass,sqlConverters是使用的同一种占位符,不然可能会出现自动生成的语句在解析的时候无法正确解析出占位情况。

5.2 占位符函数

框架中还支持在占位符中使用自定义函数,用来对属性替换的时候进行转换

如:%{trim:propertyName}  或 :trim:propertyName 

 

5.2.1 内置的函数

orm框架当前内置了如下的几种函数:

 

like   模糊查询

    where name like %{like:name}    如果name="小明"  相当与 where name like '%小明%'

leftlike   左匹配模糊查询

    where name like %{like:name}    如果name="小明"  相当与 where name like '小明%'

rightlike   右匹配模糊查询

    where name like %{like:name}    如果name="小明"  相当与 where name like '%小明'

 

startdate 用于构建一个用于起始查询的时间

         where create_date >=%{startdate:date}  那么不管理date的值是否存在时分秒的信息 都会相当于把时分秒去掉了 where create_date>='2017-05-06'

 

enddate 用于构建一个用于起始查询的时间

         where create_date <=%{enddate:date}  那么不管理date的值是否存在时分秒的信息 都会相当于后一天的前一秒 where create_date<='2017-05-06 23:59:59'

 

5.2.2 添加自定义

需要添加自定义函数需要实现接口org.smile.function.Function

public interface Function {

    /**

     * 获取函数的值

     * @param param 函数传入的参数

     * @return 函数结果

     */

    public Object getFunctionValue(Object ...args);

    /**

     * 获取函数的名称

     * @return

     */

    public String getFunctionName();

}

 

然后把函数注册:

org.smile.db.sql.parameter.function. DefaultFunctionContext的注册方法

     /**

     * 注册一个函数

     * @param function

     */

    public void registFunction(Function function){

        functionMap.put(function.getFunctionName(), function);

    }

 

调用:

DefaultFunctionContext.instance.registFunction(function);

二、Dao接口配置

1、xml方式

1.1mapper标签

标签属性

属性

名称

必选

默认

描述

target

扩展实现类名

 

用于实现接口的扩展

template

模板类型

freemark

Sql广西模板处理

single

是否单例

true

Dao实现类是否是单例,建设都用单例

sqlType

Sql语句类型

sql

用于sql转换器的使用,在sessionFactory中配置

标签可以用多个插入 删除 更新 更新 批量 代码片断 的子标签

<snippet id="testsql">

     <![CDATA[

        <% if(name!=null&&name!=""){%>  and name in (%{name}) <%}%>

        <% if(id!=null&&id!=""){%> and id = %{id}<%}%>

     ]]>

</snippet>

 

<select id="queryStudentMap"  mapper="map">

    <![CDATA[

        select * from student where 1=1

        <#include 'testsql'>

    ]]>

</select>

 

 

1.2 操作方法标签

操作方法标签的 delete update insert select batch 5种

 

方法操作标签属性参数

属性

名称

必选

默认

描述

id

ID

 

对应dao的方法名

template

模板类型

freemark

Sql广本模板处理,如未指定使用mapper中的属性,

框架支持freemarker groovy两种方式

sql

Sql语句广西

标签体内容

true

如未指定sql语句框架会根据方法 的参数与返回值生成sql语句,但方法的参数需为数据表映射实体

sqlType

Sql语句类型

sql

用于sql转换器的使用,在sessionFactory中配置

include

Sql语句文本外部文件

 

如不指定sql 可以指定外部文件来包含sql语句

mapper

返回映射

 

如果不指定,可以从方法返回值的类型中获取,如是collection类型 则会从泛型号获取,如果泛型中指定的是接口则必需在mapper指定。

如泛型是Map 且不指定 则使用默认resultSetMap返回

 

include例子

<insert id="saveSamplingPrescriptionDetail" include="saveSamplingPrescriptionDetail.sql">

    </insert>

2、注解方式

@Update  @Delete  @Select @Insert  @Batch 几种标签 属性配置参考xml属性

例如:

@Select(sql="select s.* from TDrugSafeUseInfo s  inner join TDrugCheckAlertControl c on s.alertLevel=c.code where c.enable =1 and  s.prescriptId=:param")

public List<TDrugSafeUseInfo> drugSafeUseCheck(String prescriptId);

3、@ArrayBound 注解

         此注解用于标注此方法参数是以数组方式赋值

         如:

     @ArrayBound

    public List<ReviewedCommonInfo> queryReviewCommonReviewed(Object[] param);

    刚sql配置可以是:以? 做为占位符

    <select id="queryReviewCommonReviewed">

        <![CDATA[

            select * from TPrescriptionCommonReviewed cr

            inner join TReviewedProblemInfo pi on pi.viewTypeNo=cr.reviewClassifyNo and pi.viewProblemNo=cr.reviewIssueNo

            where cr.assignId=?

        ]]>

    </select>

4、方法参数

4.1Map参数

占位符可以是map的key 、模板中对应有也是map的key

4.2 List  数组  参数

在模板中会转成参数名称 固定 list  不论方法的参数名是什么

 

public List<SelectData> queryDepartments(String[] ids);

 

在模板中就要写 <%if(list!=null&&list.size()>0){%> and BIC05 in (:list) <%}%>  而不是写 ids

 

4.3 String Integer 无属性的类型

在模板中固定参数名为param 

 

public List<SelectData> queryApothecaryData(String orgNo);

 

在模板中写

r.role_key='ROLE_YAOSHI' and u.organization_key=:param  而不是写orgNo

 

4.4 其它自定义对象类型

模板中的变量为对象的成员变量

 

public List<TBadFeedAction> getBadFeedList(ReportQuery query);

 

模板中应为:

<select id="getBadFeedList" template="groovy" sqlType="osql">

        <![CDATA[

            select * from TBadFeedAction where 1=1

            <% if(startTime!=null&&startTime!=""){%> 

                and reportAgencyDate >= :startTime 

            <%}%>

            <% if(endTime!=null&&endTime!=""){%> 

                and reportAgencyDate <= :endTime 

            <%}%>

        ]]>

    </select>

三、BaseDAO接口

1、在Service中直接使用

         在IOC容器中配置org.smile.orm.base.BaseDAO 接口的实现类

         例如Spring窗口中可配置

         <bean id="ormDaoSupport" class="org.smile.orm.spring.DaoSupport">

        <property name="whereSqlParser">

            <bean class="org.smile.orm.base.impl.OrmWhereSqlParser"></bean>

        </property>

        <property name="dataSource" ref="dataSource"></property>

     </bean>

 

         在Service中就可以使用注解注入到属性中使用:

@Service

public class OrmBaseService {

    @Resource

    protected BaseDAO ormDaoSupport;

   

    @Resource

    protected JdbcTemplate dbTemplate;

   

   

    public void insert(List objs) throws SQLException{

        ormDaoSupport.add(objs);

    }

   

    public void add(Object obj) throws SQLException{

        ormDaoSupport.add(obj);

    }

   

    public void delete(List objs) throws SQLException{

        ormDaoSupport.deleteBatch(objs);

    }

   

    public void deleteByIds(Class clazz,Object[] ids) throws SQLException{

        ormDaoSupport.deleteByIds(clazz, ids);

    }

   

    public void updateBatch(List objs,String[] fields) throws SQLException{

        ormDaoSupport.updateBatch(objs,fields);

    }

   

    public void update(List objs)  throws SQLException{

        ormDaoSupport.updateBatch(objs);

    }

    //省略其它方法

}

2、Dao 接口继承使用

只需在Dao接口继承org.smile.orm.base.BaseDAO接口 就可以获取 接口中的方法

 

需要在sessionFactory中指定baseTarget 属性为BaseDAO的实现类。

 

<property name="baseTarget" ref="ormDaoSupport"></property>

 

 

四、IBaseDao 接口

只需在Dao接口中继承org.smile.orm.base.IBaseDao接口,就可以使dao获得了IBaseDao的方法并不需要xml配置,IBaseDao需要指定泛型,才能保存每一个dao调用update add 等方法的时候是一个类型。

 

由于此接口不存在 拼where语句的方法,可以使代码风格更加统一,但BaseDAO可能更加灵活,具有更多的方法调用方式。

1、与BaseDAO接口对比

IBaseDao:

         是使用框架自动行成sql语句方式实现

BaseDAO:

         是使用代理方式,使用实现类的方法接管

五、拦截器的使用

1、拦截器的配置

拦截器需要配置到sessionFactory的属性中,例如下就配置了3个拦截器

<property name="interceptors" >

    <list>

        <bean class="org.smile.orm.plugin.PageQueryInterceptor"></bean>

        <bean class="org.smile.orm.plugin.OrderbyInterceptor"></bean>

        <bean class="org.smile.orm.plugin.TopInterceptor"></bean>

    </list>

</property>

2、拦截器定义

         需要实现org.smile.plugin.Interceptor接口,还可以使用拦截器注解标记要拦截的方法

         例如:orderyby 插件实现

@Intercept(type=SqlConverter.class,method="convertToSql")

public class OrderbyInterceptor implements Interceptor {

 

    @Override

    public Object plugin(Object target) {

        return Plugin.wrap(target, this);

    }

 

    @Override

    public Object intercept(Invocation invocation) throws Exception {

        OrderbyParam pageParam=OrderbyHelper.getOrderbyParam();

        if(CollectionUtils.isEmpty(pageParam)){

            return invocation.proceed();

        }else{

            try{

                Object[] args=invocation.getArgs();

                MappedOperator operator=(MappedOperator)args[1];

                if(operator.getOperator() instanceof SelectOperator){

                    String sql=(String)(args[0]);

                    invocation.setArgs(new Object[]{doOrderby(sql, pageParam),args[1],args[2]});

                }

                return invocation.proceed();

            }finally{

                OrderbyHelper.remove();

            }

        }

    }

 

    private String doOrderby(String sql,OrderbyParam pageParam){

        StringBuffer sb=new StringBuffer(sql);

        sb.append(" ORDER BY ");

        int index=0;

        for(Map.Entry<String, String> entry:pageParam.entrySet()){

            sb.append(entry.getKey()).append(entry.getValue());

            if(index<pageParam.size()-1){

                sb.append(",");

            }

        }

        return sb.toString();

    }

}

就指定了拦截SqlConverter接口的convertToSql方法

 

3、预设的拦截器使用

框架当前已经开发3个常的拦截器插件,分别是分页插件、排序插件、Top插件

3.1分页插件

只需要在调用查询方法之前,使用PagerHelper.startPager(pageint, pageSizeint); 方法进行分页即可使用自动分页效果

 

int pageint=Integer.valueOf(page);

int pageSizeint=Integer.valueOf(pageSize);

PagerHelper.startPager(pageint, pageSizeint);

3.2排序插件

只需要在调用查询方法前使用OrderbyHelper进行排序即可

OrderbyParam p=new OrderbyParam();

p.orderby(orderby, desc);

OrderbyHelper.oderby(p);

3.3 Top插件

在调用查询方法之前使用TopHelper进行操作

int topInt=Integer.parseInt(top);

TopHelper.startTop(topInt);

附录:

1、其中使用到的groovy 表达式 与 freemarker模板的知识请参考网上的资料,这些资料很齐全

 

 

2、些框架的使用也可参考hibernate 与 mybatis的使用方式,如果具有mybatis的基础学习起来可事半功倍

 

3、更多orm框架的内容,还需要使用中总结心得。

 

转载于:https://my.oschina.net/huzhsh/blog/871747

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值