Ibatis2.0使用说明——配置篇(4)

【拯救C盘】一文搞懂Windows修改Anaconda默认的虚拟环境存放路径及其原理 Anaconda创建的虚拟环境可能会默认保存在C盘,但C盘的存储空间很宝贵,由于每个虚拟环境的大小可能达到n个GB,稍不注意就会遇到C盘红色警告。因此有必要做点什么来拯救被虚拟环境占用的大部分空间!!! 阅读详情
 

Parameter Maps and Inline Parameters

 
<parameterMap id="parameterMapName" [class="Author"]>
       <parameter property ="propertyName" [jdbcType="VARCHAR"] [javaType="string"]
       [nullValue="NUMERIC"] [null="-9999999"]/>
       <parameter …… />
       <parameter …… />
</parameterMap>
括号[]中是可选的属性。parameterMap 元素的id 属性作为唯一标识,在同一个SQL Map XML 文件中不能重名。一个parameterMap 可包含任意多的property 元素。

一、property

property属性是指传入mapped statement中的JavaBean参数对象的属性名。这个属性名可以使用多次,这要看在这个statement中,这个属性名要出现多少次。例如:
<parameterMap id="authorParameter3" class="Author">
       <parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
       <parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<update id="updateAuthor2" parameterMap="authorParameter2">
       UPDATE author set auth_name=? WHERE auth_name = ?
</update>
但是如果使用这样的方法的话,调用代码应该是:
Author author = new Author();
author.setName("作者三");
sqlMapClient.update("updateAuthor2", paraMap);
那么它其实执行的是:
UPDATE author set auth_name='作者三' WHERE auth_name = '作者三'
这样的话,就根本没有了意义,因为,你只能传进一个Author对象,而这个Author对象的name属性值将会被用在整个Sql语句中,而一般的情况下是不应该相同的,也就是说,我们的本意可能是想:
UPDATE author set auth_name='作者N' WHERE auth_name = '作者三'
方法倒是有,不过我觉得不太好。
<parameterMap id="authorParameter2" class="java.util.HashMap">
       <parameter property="name1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
       <parameter property="name2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<update id="updateAuthor2" parameterMap="authorParameter2">
       UPDATE author set auth_name=? WHERE auth_name = ?
</update>
调用代码为:
HashMap paraMap = new HashMap();
paraMap.put("name1", "作者N");
paraMap.put("name2", "作者三");
sqlMapClient.update("updateAuthor2", paraMap);
如果你想到更好的方法解决这个问题的话,请不吝赐教。

二、 jdbcType

jdbcType用于指明数据库的字段类型。如果不说明字段类型的话,一些JDBC驱动程序就无法确定要操作的字段类型。例如:PreparedStatement.setNull(int parameterIndex, int sqlType)方法,要求指定数据类型。如果不指定数据类型,某些Driver 可能指定为Types.Other 或Types.Null。但是,不能保证所有的Driver 都表现一致。对于这种情况,SQL Map API 允许使用parameterMap 元素的jdbcType 属性指定数据类型。
正常情况下,只有当字段可以为NULL或日期时间类型时才需要type 属性。因为Java 只有一个Date 类型(java.util.Date),而大多数SQL 数据库有多个-通常至少有3 种。因此,需要指定字段类型是DATE 还是DATETIME。
Type 属性可以是JDBC Types 类中定义的任意参数的字符串值。虽然如此,还是有某些类型不支持(即BLOB)。
注意!大多数JDBC Driver 只有在字段可以为NULL 时需要指定type 属性。因此,对于这些Driver,只是在字段可以为NULL 时才需要指定type 属性。
注意!当使用Oracle Driver 时,如果没有给可以为NULL 的字段指定type 属性,当试图给这些字段赋值NULL 时,会出现"Invalid column。 type"错误。

三、javaType

javaType用于指明作为参数传递的java bean的属性的类型。通常情况下,这可以通过反射机制从java bean中获取类型,但是一些特定的映射,比如说MAP和XML的映射就无法将类型信息传递给框架了。如果java type没有设置而且框架无法获知类型的话,那么这个类型会被指定为Object。
属性 nullValue的值可以是对于property 类型来说合法的任意值,用于指定NULL 的替换值。就是说,当Java Bean的属性值等于指定值时,相应的字段将赋值NULL。这个特性允许在应用中给不支持null的数据类型(即int,double,float等)赋值null。当这些数据类型的属性值匹配nullValue值(即匹配-9999)时,NULL 将代替nullValue 值写入数据库。
例如:
<parameterMap id="authorParameter" class="Author">
       <parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
       <parameter property="age" jdbcType="INTEGER" javaType="java.lang.Integer" nullValue="-999" mode="INOUT"/>
       <parameter property="telephone" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
       <parameter property="address" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
</parameterMap>
<insert id="insertAuthor1" parameterMap="authorParameter">
       INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (?,?,?,?)
</insert>
您可以在另一个SQL Map XML 文件中引用parameterMap。例如,要在另一个文件中引用上面的parameterMap,可以使用名称"Product.insert-product-param"。
使用Inline Parameter Maps,可以把Java Bean 的属性名称嵌在mapped-statement 的定义中(即直接写在SQL 语句中)。
例如:
<insert id="insertAuthor1" parameterClass="Author">
       INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (#name#,#age#,#telephone#,#address#)
</insert>
这样,在你的Author类中,要有name,age,telephone,address的属性以及相应的get和set方法,这样做可以避免使用另外定义parameterMap的麻烦。
你也可以在内嵌参数中指定数据类型和nullValue,例如:
<insert id="insertAuthor1" parameterClass="Author">
       INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (#name:VARCHAR:NO_ENTRY#,#age:INTEGER:-999#,#telephone:VARCHAR:NO_ENTRY#,#address:VARCHAR:NO_ENTRY#)
</insert>
注意!在内嵌参数中,要指定NULL 的替代值,必须要先指定数据类型。
注意!如需要在查询时也使用NULL 替代值,必须同时在resultMap 中定义。
注意!如果您需要指定很多的数据类型和NULL 替代值,可以使用外部的parameterMap元素,这样会使代码更清晰。
在SQL Map 架构中,Result Map 是极其重要的组件。在执行查询Mapped Statement 时,resultMap 负责将结果集的列值映射成Java Bean 的属性值。resultMap 的结构如下:
<resultMap id="resultMapName" class="some.domain.Class" [extends="parent-resultMap"]>
       <result property="propertyName" column="COLUMN_NAME"
                     [columnIndex="1"] [javaType="int"] [jdbcType="NUMERIC"]
                     [nullValue="-999999"] [select="someOtherStatement"]
                     />
       <result ……/>
       <result ……/>
       <result ……/>
</resultMap>
括号[]中是可选的属性resultMap 也有class 属性,是Java 类的全限定名(即包括包的名称)或该类的别名。该Java 类初始化并根据定义填充数据。
Extends 是可选的属性,可以设定成以为基础的另外一个resultMap 的名字。和在Java 中继承一个类相似,父resultMap 的属性将作为子resultMap 的一部分。父resultMap 的属性总是加到子resultMap 属性的前面,并且父resultMap 必须要在子resultMap 之前定义。父resultMap 和子resultMap 的class 属性不一定要一致,它们可以没有任何关系。
resultMap 可以包括任意多的property 映射,将查询结果集的列值映射成Java Bean 的属性。属性的映射按它们在resultMap中定义的顺序进行。属性class 必须符合Java Bean 规范,每一属性都必须拥有get/set 方法。
注意!ResultSet 的列值按它们在resultMap 中定义的顺序读取。
property属性是指从mapped statement中返回的JavaBean对象的属性名。这个属性名也可以使用多次。
column属性值是ResultSet中的列名字,即字段名,取得的这个字段的值将赋给property所指的bean属性。
可选属性,用于改善性能。属性columnIndex 的值是ResultSet 中用于赋值Java Bean属性的字段次序号。在99%的应用中,不太可能需要牺牲可读性来换取性能。使用columnIndex,某些JDBC Driver可以大幅提高性能,某些则没有任何效果。
同ParameterMap中的jdbcType
同ParameterMap中的javaType
属性nullValue指定数据库中NULL的替代值。因此,如果从ResultSet中读出NULL值,JavaBean属性将被赋值为属性nullValue指定的替代值。
如果数据库中存在NULLABLE 属性的字段,但您想在你的应用程序中用指定的常量代替NULL,您可以这样做:
<resultMap id="get-product-result" class="Author">
       <result property="id" column="auth_id"/>  
       <result property="age" column="auth_age"/>
       <result property="name" column="auth_name" nullValue="you have no name"/>
</resultMap>
在上例中,如果取得的记录中auth_name字段的值为NULL,那么在赋给java bean的时候,name属性将被赋为"you have no name"。
如果在一个类与另一个类之间是关联关系的话,那么当你用JDBC取得记录的时候,这个关联关系是如何实现的呢?例如这样的关系:一个作者可能会有多个文章发表,那么作者与文章之间就是很强的关联关系,而且是一对多的关系,在Author的Bean中是这样写的:
public class Author
{
    private int id;
.....
    private List articleList;
       public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id=id;
    }
 
       ... ...
   
       public List getArticleList()
    {
        return articleList;
    }
   
    public void setArticleList(List articleList)
    {
        this.articleList=articleList;
    }
}
当你执行一条sql语句从数据表author中取出相应的数据的时候,在上面的java bean中,articleList如何赋值呢?这时候,就需要使用select属性。

1.1:1关系:

我们先假设在author和article之间使用1:1的关系,虽然在真实世界中是不正确的,我们只是做个例子,那么Author和article的bean代码如下:
public class Author
{
    private int id;
    private int age;
    private String name;  
    private String address;
    private String telephone;
    private Article article;
      
    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id=id;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age=age;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name=name;
    }
   
    public String getAddress()
    {
        return address;
    }
    public void setAddress(String address)
    {
        this.address=address;
    }
    public String getTelephone()
    {
        return telephone;
    }
    public void setTelephone(String telephone)
    {
        this.telephone=telephone;
    }
 
       public Article getArticle()
    {
        return this.article;
    }
          
    public void setArticle(Article article)
    {
        this.article=article;
    }
}
 
public class Article
{
    private int id;
    private String title;
    private Date createtime;
    private int author;
   
    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id=id;
    }
    public String getTitle()
    {
        return title;
    }
    public void setTitle(String title)
    {
        this.title=title;
    }
    public Date getCreatetime()
    {
        return createtime;
    }
    public void setCreatetime(Date createtime)
    {
        this.createtime=createtime;
    }
    public int getAuthor()
    {
        return author;
    }
    public void setAuthor(int author)
    {
        this.author=author;
    }
}
在author.xml的配置如下:
<resultMap id="linkResultMap1" class="Author">
       <result property="id" column="auth_id"/>  
       <result property="age" column="auth_age"/>
       <result property="name" column="auth_name"/>
       <result property="telephone" column="auth_tel"/>
       <result property="address" column="auth_address"/>
       <result property="article" column="auth_id" select="getLinkArticle1"/>
</resultMap>
<select id="getAuthor5" resultMap="linkResultMap1" parameterClass="int">
       SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle1" resultClass="com.ibatis.beans.Article" parameterClass="int">
       SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = #id#
</select>
调用代码如下:
Author author = (Author)sqlMapClient.queryForObject("getAuthor5", new Integer(1));
System.out.println(author.getName()+"'s article is :"+author.getArticle().getTitle());
你可以看到,对于Author类中的article属性,IBatis是将取得的记录的auth_id字段值作为参数传入到id="getLinkArticle1"的语句中,并将取得的结果封装成Article对象,并赋给Author的article属性。上面的调用代码实际执行的两条sql语句是:
SELECT * FROM author WHERE auth_id = 1
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = 1
在第二条语句中,将取得的记录封装成Article对象,并赋给Author的article属性,所以,你可以直接使用author.getArticle().getTitle()获得文章的标题。
上面的方法显示了如何实现1:1的关联关系,但是上面的方法并不好,原因是可能会执行很多次查询!
(1)避免 N+1 Selects (1:1)
如果上面的配置如下:
<resultMap id="linkResultMap1" class="Author">
       <result property="id" column="auth_id"/>  
       <result property="age" column="auth_age"/>
       <result property="name" column="auth_name"/>
       <result property="telephone" column="auth_tel"/>
       <result property="address" column="auth_address"/>
       <result property="article" column="auth_id" select="getLinkArticle1"/>
</resultMap>
<select id="getAuthor5" resultMap="linkResultMap1" parameterClass="int">
       SELECT * FROM author WHERE auth_id > #id#
</select>
<select id="getLinkArticle1" resultClass="com.ibatis.beans.Article" parameterClass="int">
       SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = #id#
</select>
调用代码如下:
Author author = (Author)sqlMapClient.queryForList("getAuthor5", new Integer(1));
如果SELECT * FROM author WHERE auth_id > 1的记录有N条,那么将对id="getLinkArticle1"的语句执行N次查询,这样所有的查询总数将为N+1次,执行效率会很低。
这时,可以使用下面的联合查询的方法来解决:
<resultMap id="linkResultMap2" class="Author">
       <result property="id" column="auth_id"/>  
       <result property="age" column="auth_age"/>
       <result property="name" column="auth_name"/>
       <result property="telephone" column="auth_tel"/>
       <result property="address" column="auth_address"/>
       <result property="article.title" column="art_title"/>
</resultMap>
<select id="getAuthor6" resultMap="linkResultMap2" parameterClass="int">
       <![CDATA[ SELECT a.auth_id,a.auth_age,a.auth_name,a.auth_tel,a.auth_address,b.art_title FROM author a,article b WHERE a.auth_id > #id# and a.auth_id = b.art_id]]>
</select>
调用代码为:
Author author = (Author)sqlMapClient.queryForList("getAuthor6", new Integer(1));
这样只用一条Sql语句就可以解决。

2.1:M与M:N关系:

下面我们讨论1:M的关系,一个author可能有多个article,所以,author与article之间是一对多的关系。那么我们在Author类中加入如下代码(在省略号间的是要加入的代码):
public class Author
{
... ...
       private List articleList;
    public List getArticleList()
    {
        return articleList;
    }
   
    public void setArticleList(List articleList)
    {
        this.articleList=articleList;
    }
... ...
}
配置如下:
<resultMap id="linkResultMap3" class="Author">
       <result property="id" column="auth_id"/>  
       <result property="age" column="auth_age"/>
       <result property="name" column="auth_name"/>
       <result property="telephone" column="auth_tel"/>
       <result property="address" column="auth_address"/>
       <result property="articleList" column="auth_id" select="getLinkArticle3"/>
</resultMap>
<select id="getAuthor7" resultMap="linkResultMap3" parameterClass="int">
       SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle3" resultClass="com.ibatis.beans.Article" parameterClass="int">
       SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_author = #id#
</select>
调用代码为:
Author author = (Author)sqlMapClient.queryForObject("getAuthor7", new Integer(1));
System.out.println(author.getName()+"的文章有:");
for(int i=0;i<author.getArticleList().size();i++)
{
       int num=i+1;
       Article art = (Article)author.getArticleList().get(i);
       System.out.println(num+". "+art.getTitle());
}
从上面的实现可以看出,你只需要在bean中加入一个java.util.List(或java.util.Collection)类型的articleList来表示所有的文章列表即可,调用部分没有什么变化,IBaits会自动从Article中取得的记录封装成Article对象并加入到一个List对象中,然后将这个List对象赋值给Author类的articleList属性。
(1)避免 N+1 Selects (1:M and M:N)
1:M和M:N的情况与1:1的情况相似,也会出现N+1 Selects 的情况,但是到目前位置,还没有其他的方法来解决这个问题,希望在不久的将来能够解决。

3.多个复杂参数属性

你可能已经注意到了,上面的例子中,在resultMap中只指明了一个column属性用于id=”getLinkArticle”的statement关联。其实,Ibatis允许你指明多个column属性与id=”getLinkArticle”的statement关联,语法很简单, {param1=column1, param2=column2, …, paramN=columnN}。下面是一个例子:
<resultMap id="linkResultMap4" class="Author">
    <result property="id" column="auth_id"/>
    <result property="age" column="auth_age"/>
    <result property="name" column="auth_name"/>
    <result property="telephone" column="auth_tel"/>
    <result property="address" column="auth_address"/>
    <result property="articleList" column="{id=auth_id,address=auth_address}" select="getLinkArticle4"/>
</resultMap>
<select id="getAuthor8" resultMap="linkResultMap4" parameterClass="int">
    SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle4" resultClass="com.ibatis.beans.Article" parameterClass="int">
    SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_author = #id# and art_publish_add=#address#
</select>
你也可以只写字段的名称,只要按照所关联的statement中所对应的字段顺序即可,象这样:
{auth_id,auth_address}
上面的这个例子我在Mysql的环境中运行没有通过,报出的错误是:Column'{auth_id,auth_address}' not found.
这个错误是与JDBC驱动无关的,而是在做XML解析的时候发生的错误,不知道是什么原因,如果您有这样的成功经历的话,希望能共同分享,我的Email是:tenwang1977@163.com
注意:有些JDBC驱动不支持同时打开多个ResultSets(单个连接)。所以说,这样的驱动不能完成复杂对象的映射,因为JDBC驱动需要多个ResultSets的连接,这时候,只能使用一个关联查询解决问题。
如果你使用Microsoft SQL Server 2000 的JDBC驱动的话,你需要在配置url的时候,在url后加上SelectMethod=Cursor。

4.在Parameter Maps and Result Maps中支持的参数

Java Type
JavaBean/Map
Property Mapping
Result Class /
Parameter Class***
Type Alias**
boolean
YES
NO
boolean
java.lang.Boolean
YES
YES
boolean
byte
YES
NO
byte
java.lang.Byte
YES
YES
byte
short
YES
NO
short
java.lang.Short
YES
YES
short
int
YES
NO
Int/ Integer
java.lang.Integer
YES
YES
Int/ Integer
long
YES
NO
long
java.lang.Long
YES
YES
long
float
YES
NO
float
java.lang.Float
YES
YES
float
double
YES
NO
double
java.lang.Double
YES
YES
double
java.lang.String
YES
YES
string
java.util.Date
YES
YES
date
java.math.BigDecimal
YES
YES
decimal
* java.sql.Date
YES
YES
N/A
* java.sql.Time
YES
YES
N/A
* java.sql.Timestamp
YES
YES
N/A
<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”cache-size” value=”1000” />
</cacheModel>
上面的cache model 创建了一个名为“product-cache”的缓存,使用“最近最少使用”(LRU)实现,每24小时,缓冲区将刷新一次,而且在执行insertProduct、updateProduct和deleteProduct的statement时,缓冲区也将刷新,设定的时间可以设定为hours, minutes, seconds或 milliseconds。一些Cache的实现需要附加的属性,比如说上例中的cache-size
 属性,cache的大小指明了可以存放在cache中的实体的个数。type属性的名称要么是全限定的类名,要么是缓存实现的别名。Cache Model 使用插件的形式来支持不同的缓存算法。它的实现在cache-model 元素的type属性中指定(如上所示)。
(一)Read-Only 与 Read/Write
Ibatis支持只读和可读写的Cache,只读的Cache可以在所有的用户间共享,所以它可以提供更大的操作空间。但是从只读缓冲中读取的对象不能够被修改。如果你要对你取得的对象进行修改的话,那么你只能用可读写的缓冲。readOnly=”true”为只读缓冲;readOnly=”false”为可读写缓冲。
(二)Serializable Read/Write Caches
要使用Serializable Read/Write Caches,设置readOnly=”false”,serialize=”true”。默认情况下,采用的是readOnly=” true”,serialize=”false”。
目前包括以下的4 个缓冲类型实现:
1. “MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)
MEMORY cache 实现使用reference 类型来管理cache 的行为。垃圾收集器可以根据reference 类型判断是否要回收cache 中的数据。MEMORY 实现适用于没有统一的对象重用模式的应用,或内存不足的应用。
MEMORY 实现可以这样配置:
<cache-model name="product-cache" implementation ="MEMORY">
       <flush-interval hours="24"/>
       <flush-on-execute statement="insertProduct"/>
       <flush-on-execute statement="updateProduct"/>
       <flush-on-execute statement="deleteProduct"/>
       <cache-property name=”reference-type” value=”WEAK” />
</cache-model>
MEMORY cache 实现只认识一个<cache-property>元素。这个名为“reference-type”属性的值必须是STRONG,SOFT 和WEAK 三者其一。这三个值分别对应于JVM 不同的内存reference 类型。
(1) WEAK(缺省)
大多数情况下,WEAK类型是最佳选择。如果不指定类型,缺省类型就是WEAK。它能大大提高常用查询的性能。但是对于当前不被使用的查询结果数据,将被清除以释放内存用来分配其他对象。
(2) SOFT
在查询结果对象数据不被使用,同时需要内存分配其他对象的情况下,SOFT类型将减少内存不足的可能性。然而,这不是最具侵入性的reference类型,结果数据依然可能被清除。
(3) STRONG
确保查询结果数据一直保留在内存中,除非Cache被刷新(例如,到了刷新的时间或执行了更新数据的操作)。
对于下面的情况,这是理想的选择:
1” 结果内容数据很少
2” 完全静态的数据
3” 频繁使用的数据
优点是对于这类查询性能非常好。缺点是,如果需要分配其他对象,内存无法释放(可能是更重要的数据对象)。
2. “LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController)
LRU Cache 实现用“最近最少使用”原则来确定如何从Cache 中清除对象。当Cache溢出时,最近最少使用的对象将被从Cache 中清除。
<cache-model name="product-cache" implementation ="LRU">
       <flush-interval hours="24"/>
       <flush-on-execute statement="insertProduct"/>
       <flush-on-execute statement="updateProduct"/>
       <flush-on-execute statement="deleteProduct"/>
       <cache-property name=”cache-size” value=”1000” />
</cache-model>
值得注意的是,这里指的对象可以是任意的,从单一的String 对象到Java Bean 的ArrayList 对象都可以。因此,不要Cache 太多的对象,以免内存不足。
3. “FIFO” (com.ibatis.db.sqlmap.cache.fifo.FifoCacheController)
FIFO Cache 实现用“先进先出”原则来确定如何从Cache 中清除对象。对于短时间内持续引用特定的查询而后很可能不再使用的情况,FIFO Cache 是很好的选择。
<cache-model name="product-cache" implementation ="FIFO">
       <flush-interval hours="24"/>
       <flush-on-execute statement="insertProduct"/>
       <flush-on-execute statement="updateProduct"/>
       <flush-on-execute statement="deleteProduct"/>
       <cache-property name=”cache-size” value=”1000” />
</cache-model>
值得注意的是,这里指的对象可以是任意的,从单一的String 对象到Java Bean 的ArrayList 对象都可以。因此,不要Cache 太多的对象,以免内存不足。
4. “OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController)
OSCACHE Cache 实现是OSCache2.0 缓存引擎的一个Plugin。它具有高度的可配置性,分布式,高度的灵活性。
<cache-model name="product-cache" implementation ="OSCACHE">
       <flush-interval hours="24"/>
       <flush-on-execute statement="insertProduct"/>
       <flush-on-execute statement="updateProduct"/>
       <flush-on-execute statement="deleteProduct"/>
</cache-model>
OSCACHE 实现不使用cache-property 元素。而是在类路径的根路径中使用标准的oscache.properties 文件进行配置。在oscache.properties 文件中,您可以配置Cache 的算法(和上面讨论的算法很类似),Cache 的大小,持久化方法(内存,文件等)和集群方法。
要获得更详细的信息,请参考OSCache 文档。OSCache 及其文档可以从OpenSymphony网站上获取:http://www.opensymphony.com/oscache/
OpenClaw进阶实战(二十三):微信公众号接入——被动回复、客服消息、素材管理 本文介绍了将OpenClaw接入微信公众号的完整方案,重点包含以下内容: 接入方案选型:对比官方插件、三方服务和自建中转三种方式,选择自建Node.js中转服务实现灵活控制 核心原理:通过中转服务器完成微信消息协议转换,处理5秒超时限制和异步回复机制 实战开发: 搭建Express中转服务 实现Token管理和消息处理 采用内存缓存对话历史 通过客服接口异步回复 官方插件方案:介绍2026年发布的ClawBot插件,支持文本/图片/文件收发 进阶功能:包括素材管理接口调用示例 该方案适用于需要深度定制公众号 阅读详情

相关推荐

利用eds editor生成CANOPEN 设备eds文件

通过以上步骤,您可以根据实际设备的功能特性,自动生成一份符合CANopen协议标准的电子数据表(EDS文件),该文件可以被上位机软件或其他CANopen主站设备用于识别、配置和控制您的CANopen从站设备。使用CANopen EDS Editor生成CANOPEN设备的EDS文件是一个系统化的过程,它涉及将设备的具体技术参数和功能映射到CANopen规范定义的对象字典中。

weixin_38604759的博客 6458

Ibatis2.0使用说明(二)——配置篇(4)

文章转载自互联网,如果您觉得我们侵权了,请联系管理员,我们会立刻处理。 Parameter Maps and Inline Parameters <parameterMap id="parameterMapName" [class="Author"]> <parameter property ="propertyNam...

weixin_34226182的博客 236

【UE5】UE5 Dedicated Server专用服务器与网络同步

这篇文章是个人在学习UE4的网络同步方面的内容的一些记录,因为UE5出来了,顺带也一起熟悉熟悉UE5,所以也就直接使用UE5来实践了。说句实在话,UE4网络同步这块确实挺难的,我自己在网上搜索的博客的内容要么停留在很浅层面只搭建一个ds服务器,要么就直接深入源码去剖析UE4的网络机制,处在中间层面的内容少之又少,不得不自己好一阵研究,强烈推荐这几位博主的博文,我在学习的过程中也从中受益匪浅。 Ken_An、风蚀之月、 刘东无敌还有我师傅推荐给我的一本关于UE4网络的PDF。 一、什么是Dedicated

Goulandis 3万+

iBatis中使用XML

本文系[url=http://www.iteye.com/blogs/subjects/ibatisdev]iBatis开发详解[/url]系列文章之在iBatis中使用XML 在实际应用中,很多时候我们使用到了XML格式的数据,比如FushionChart,iBatis允许使用XML作为数据库查询操作的参数,也允许数据库查询结果返回一个XML格式的数据。如果不是必须,使用XML...

nanlei1987的专栏 499

ENSP:小型企业网络拓扑设计

包含的技术:ospf、dhcp中继、ac+ap、vrrp+mstp、acl、浮动路由、静态路由、vlan划分

weixin_45921302的博客 1万+

Android Framework WMS全面概述和知识要点

WindowManagerService 类是整个 WMS 的核心大脑,处于系统服务层,负责协调和管理所有与窗口相关的操作。它在 Android 系统架构中起到承上启下的关键作用,向上对接应用层的窗口请求,向下与 SurfaceFlinger 等底层组件交互,确保窗口能够正确地在屏幕上显示和管理。

大模型大数据攻城狮的专栏 1792

Ibatis2.0使用说明(一)——入门实例篇[原]

本文章将从一个Ibatis的具体示例,帮助你快速了解IBatis框架。一个简单的IBatis应用包含以下基本步骤:一、 配置文件1. 配置SqlMapConfig.properties文件2. 配置SqlMapConfig.xml文件3. 配置SqlMap.xml文件(可能有多个文件,一般情况下,可以一个表对应一个SqlMap.xml文件,文件名称可以与表名相同)注意:上面所述

猴子腿儿的Blog 3658

Qt入门教程【数据类型篇】数值类型

Qt中的数值类型

小鱼酱的博客 1万+

Ibatis使用

部分参考:https://blog.csdn.net/shixiaoguo90/article/details/49949445 Apache iBatis是当前IT项目中使用很广泛的一个半自动ORM框架,区别于Hibernate之类的全自动框架,iBatis对数据库的操作拥有更加灵活的控制,对于那些经常需要调用本地数据库函数自定义SQL语句,或是喜欢自己优化SQL执行效率的开发者来说,iBatis是一个非常不错的选择。而得到广泛应用的开源企业架构SpringFramework,也很好的将其进行了集成,使

qinwenjng120的博客 1176

WPS文档中心和文档中台 operate 未授权访问漏洞(CVE-2025-0717)

WPS文档中心和文档中台的/open/v6/api/etcd/operate?key=/config/storage&method=get接口存在未授权访问漏洞,攻击者可通过该漏洞获取AK/SK密钥等信息,这些密钥通常用于系统内部认证和权限控制,泄露后可能导致攻击者进一步修改K8s配置、部署恶意容器或执行远程命令,最终实现对系统的完全控制。

李同學AI安全 903

SAP 系统间信任关系配置全攻略:从 SM59 到 SMT1 的实践与风险控制

本文介绍了在SAP系统间配置信任关系的详细流程与最佳实践。文章以SAP Gateway与后端系统架构为场景,从SM59创建RFC目的地开始,到SMT1建立信任关系,再到授权对象S_RFCACL的配置,提供了完整的操作指南。重点包括:使用标准命名规范创建专用RFC连接、通过向导完成系统间信任登记、严格控制S_RFCACL授权范围等。文中还分享了真实项目案例、可复用的检查清单以及常见问题的排查思路,帮助用户实现稳定可靠的跨系统无密码调用,同时确保安全性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 323

mysql ibatis xml配置 like_ibatis配置xml文件中CDATA的用法

ibatis作为一种半自动化的OR Mapping工具,其灵活性日益体现出来,越来越多的人都倾向于在项目中使用。由于Sql中经常有与xml规范ibatis作为一种半自动化的OR Mapping工具,其灵活性日益体现出来,越来越多的人都倾向于在项目中使用。由于Sql中经常有与xml规范相冲突的字符对xml映射文件的合法性造成影响。许多人都知道使用标记来避免冲突,但是在sql配置中有动态语句的时候,还...

weixin_34138673的博客 231

[网络安全提高篇] 一二〇.恶意软件动态分析经典沙箱Cape批量提取动态API特征

这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您喜欢,一起进步。前文详细介绍动态分析沙箱Cape的安装过程,其是一个开源的自动恶意软件分析系统,通过自动运行和分析恶意软件,全面分析和提取恶意软件的关键特征。然而,当样本数量增加时,单个样本分析会降低效率。这篇文章将讲解如何实现Cape沙箱的批量分析,通过调用Python脚本文件来实施批量处理,并将分析结果存储在指定位置,最后补充submit.py的参数及Python调用方式。基础性文章,希望对您有帮助!

杨秀璋的专栏 4121

Ibatis2.0使用说明(二)——配置篇(4)[原]

五、Parameter Maps and Inline Parameters              [nullValue="NUMERIC"] [null="-9999999"]/>              括号[]中是可选的属性。parameterMap 元素的id 属性作为唯一标识,在同一个SQL Map XML 文件中不能重名。一个parameterMa

猴子腿儿的Blog 2311

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Ibatis2.0使用说明

 Ibatis2.0使用说明(二)——配置篇(4)     五、Parameter Maps and Inline Parameters              [nullValue="NUMERIC"] [null="-9999999"]/>              括号[]中是可选的属性。parameterMap 元素的id 属性作为唯一标识,在同一个SQL Map

y_mo的专栏 954

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Ibatis2.0使用说明——配置篇(3)

 statement中的参数简介:1. parameterClassparameterClass 属性的值是Java类的全限定名(即包括类的包名)。parameterClass属性是可选的,目的是限制输入参数的类型为指定的Java 类。虽然Parameter-class属性是可选的,建议你为每一个SQL都指定parameterClass。如果不指定parameterClass

hjpengjava的专栏 536

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Ibatis2.0使用说明——配置篇(1)

 一、 SQL Map XML 配置文件SQL Map 使用XML 配置文件集中的配置不同的设置属性,包括DataSource 的详细配置信息,SQL Map 和其他可选属性,如线程管理等。以下是SQL Map 配置文件的一个例子:SqlMapConfig.xmlPUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN""http://www.ibat

hjpengjava的专栏 482

Ibatis2.0使用说明——配置篇(2)

 sqlMap所包含的标签                                                                                                                                                           

hjpengjava的专栏 440

ibatis2.0使用procedure

之前的公司是互联网基本上会规避procedure这种东西,有的话也会是比较简单的实现.到了新公司全部使用procedure(原因不详,个人觉得是拍脑袋决定).ibatis2 2.1.7.597版本中的dtd有bug,会直接导致无法识别parameterMap标签下子标签resultMap!而是用比较高的版本会有jdbcType="ORACLECURSOR"无法支持的情况!后来发现使用2.3.4.7...

crazy java 604

IBatis使用浅析

ibatis 历史 Eight years ago in 2002, I created the iBATIS Data Mapper and introduced SQL Mapping as an approach to persistence layer development. Shortly thereafter, I donated the iBATIS name and code ...

liangwenrong的博客 1万+

iBATIS框架理论学习篇

iBATIS框架学习[20070409] 作者:kimsoft自己整理的对iBATIS框架的一些简单理论知识,有助于进一步了解和深入学习iBATIS框架,错误或不当之处,在所难免。1、什么是iBATIS1.1作者       Clinton Begin,很牛X的名字1.2背景故事    Clinton Begin于2001年启动iBATIS项目,最先的焦点是发展密码软件解决方案

我的世界我的梦 2067

iBatis2MyBatis:轻松实现iBatis到MyBatis的自动化迁移

在现代软件开发中,框架的迭代更新是不可避免的趋势。对于长期使用iBatis进行持久层管理的老旧项目来说,迁移到功能更强大、社区支持更广泛的MyBatis成为了许多开发者的必然选择。今天,我们将深入介绍一个实用且高效的开源工具——iBatis2MyBatis转换器。 ## 项目概述 iBatis2MyBatis是一个轻量级的自动化迁移工具,专门设计用于将现有的iBatis SQL映射文件转换为M

gitblog_00210的博客 1047

Ibatis2.0使用说明(一)——入门实例篇

本文章将从一个Ibatis的具体示例,帮助你快速了解IBatis框架。一个简单的IBatis应用包含以下基本步骤:一、 配置文件1. 配置SqlMapConfig.properties文件2. 配置SqlMapConfig.xml文件3. 配置SqlMap.xml文件(可能有多个文件,一般情况下,可以一个表对应一个SqlMap.xml文件,文件名称可以与表名相同)注意:上面所述

2853

Ibatis2.0使用说明(二)——配置篇(3)

 statement中的参数简介:1. parameterClassparameterClass 属性的值是Java类的全限定名(即包括类的包名)。parameterClass属性是可选的,目的是限制输入参数的类型为指定的Java 类。虽然Parameter-class属性是可选的,建议你为每一个SQL都指定parameterClass。如果不指定parameterClass 参数,任何带有合适属

chaoma96的专栏 453

Ibatis2.0使用说明(二)——配置篇(1)

一、 SQL Map XML 配置文件SQL Map 使用XML 配置文件集中的配置不同的设置属性,包括DataSource 的详细配置信息,SQL Map 和其他可选属性,如线程管理等。以下是SQL Map 配置文件的一个例子:SqlMapConfig.xmlPUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN""http://www.ibatis.

chaoma96的专栏 529
上一篇: Ibatis2.0使用说明——配置篇(3)
下一篇: js 屏蔽/启用enter鍵
hjpengjava
博客等级 码龄18年 5粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值