Files
redkale/source.html
RedKale 4bb2c25735
2016-01-30 10:27:56 +08:00

237 lines
31 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Redkale - 全新的Java微服务框架</title>
<meta name="keywords" content="Redkale,redkale,java,微服务,架构"/>
<meta name="description" content="Redkale是一个全新的基于Java 8的微服务框架"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/highlight.css" media="screen">
</head>
<body>
<section class="page-header">
<a href="index.html" class="project-name">Redkale</a>
<h2 class="project-tagline"></h2>
<a href="redkale.html" class="btn">Redkale 入门</a>
<a href="convert.html" class="btn">Convert 组件</a>
<a href="service.html" class="btn">Service 组件</a>
<a href="source.html" class="btn">Source 组件</a>
<a href="net.html" class="btn">Net 组件</a>
<a href="watch.html" class="btn">Watch 组件</a>
<a href="javadoc/index.html" target="_blank" class="btn">Javadoc API</a>
<a href="https://github.com/redkale/redkale" target="_blank" class="btn">Github 源码</a>
</section>
<section class="main-content">
<h3><a id="source_intro" class="anchor" href="#" aria-hidden="true"></a>Source 组件介绍</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Source 主要为数据源提供简易的操作接口,使底层的具体数据源(传统数据库、文件系统、内存数据库、Memcached/Redis缓存)对上层是透明的。其提供两种类型的数据源DataSource 和 CacheSource。DataSource 为数据库或内存数据库提供类似JPA、Hibernate的接口与功能。CacheSource 为缓存数据提供类似Memcached、Redis的接口和功能。两者也提供了异步接口(基于<a href="service.html#service_remote" target="_blank">远程模式Service</a>)。<br/></p>
<h3><a id="source_datasource" class="anchor" href="#" aria-hidden="true"></a>DataSource 入门</h3>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JPA虽然已经提供了简洁成熟的数据库操作接口但当数据、业务量很庞大的时候就显得捉襟见肘与JPA相比DataSource有以下几个特点<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、简易的过滤查询接口但仅支持简单的表关联查询。 <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、分布式的主键的分布式自增策略。 <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、动态更新变更后的数据库连接参数。 <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、读写分离的简易配置。 <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5、进程间的缓存自动同步。 <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据库操作方面常见的是过滤查询操作JPA规范中的JPQL虽然简化了SQL但是对于动态产生的过滤条件,使用者还是无法免去组装过滤条件的过程(无论JPQL还是CriteriaQuery), DataSource定义了FilterBean接口可以省略组装条件的过程FilterNode提供了类似CriteriaQuery的功能且这两种对象都可以序列化<a href="service.html#service_remote" target="_blank">远程模式Service</a>提供了基础微服务架构提倡服务之间尽量降低耦合因此DataSource仅支持简单的关联查询复杂的表关联查询或统计应放在数据分析系统中。一个服务通常部署多个进程若用JPA的缓存则进程之间的缓存无法同步而DataSource采用SNCP协议即可方便地达到自动同步缓存功能。JPA无法在主数据库异常时动态切换到备份数据库DataSource会监听<a href="#source_confxml">persistence.xml</a>文件,当文件配置发生变化时自动切换新的数据库配置。<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为了降低学习成本DataSource重用了JPA里的部分注解与配置文件使用方法基本相同与JPA用法唯一区别是注解只能标记于字段不能标记在方法上。
</p>
<table style="margin: auto;">
<tr><th>注解类名</th><th>功能描述</th></tr>
<tr><td style="text-align: left;">javax.persistence.Cacheable</td><td>标记Entity类是否需要缓存与JPA用法一致</td></tr>
<tr><td style="text-align: left;">javax.persistence.Column</td><td>标记字段只使用其name()、insertable()、updatable()属性</td></tr>
<tr><td style="text-align: left;">javax.persistence.Entity</td><td>JPA的Entity类必须标记为@Entity, 而Redkale不强制要求所以该注解一般无用</td></tr>
<tr><td style="text-align: left;">javax.persistence.GeneratedValue</td><td>仅用于标记主键是否为数据库自增长,其内值的两属性废弃</td></tr>
<tr><td style="text-align: left;">javax.persistence.GenerationType</td><td>被@GeneratedValue的属性引用在Redkale内不被使用到</td></tr>
<tr><td style="text-align: left;">javax.persistence.Id<td>标记主键字段与JPA用法一致</td></tr>
<tr><td style="text-align: left;">javax.persistence.Table<td>标记表的别名与JPA用法一致</td></tr>
<tr><td style="text-align: left;">javax.persistence.Transient<td>标记是否为表对应的字段与JPA用法一致</td></tr>
<tr><td style="text-align: center;font-size: 0.9rem;" colspan="2"><b>以下是Redkale自定义的注解</b></td></tr>
<tr><td style="text-align: left;"><b>@VirtualEntity</b></td><td>用于非数据库表对应的Entity类且仅用于开启缓存模式的DataSource</td></tr>
<tr><td style="text-align: left;"><b>@DistributeGenerator</b></td><td>标记主键是否采用分布式自增长策略,不能与@GeneratedValue同用</td></tr>
<tr><td style="text-align: left;"><b>@DistributeTables</b></td><td>当多个表的主键唯一性公用时需要该注解</td></tr>
<tr><td style="text-align: left;"><b>@FilterColumn</b></td><td>用于FilterBean过滤类的字段设置</td></tr>
<tr><td style="text-align: left;"><b>@FilterJoinColumn</b></td><td>用于FilterBean过滤类的关联表字段设置</td></tr>
<tr><td style="text-align: left;"><b>@FilterGroup</b></td><td>用于FilterBean过滤类的过滤条件分组设置</td></tr>
</table>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数据源主要使用的对象有 DataSource、FilterBean、FilterNode。DataSource 提供的接口分几种系列:
</p>
<table style="margin: auto;">
<tr><th>系列方法</th><th>功能描述</th></tr>
<tr><td style="text-align: left;">insert</td><td>插入数据</td></tr>
<tr><td style="text-align: left;">delete</td><td>删除数据</td></tr>
<tr><td style="text-align: left;">update</td><td>更新数据</td></tr>
<tr><td style="text-align: left;">updateColumnXXX</td><td>更新数据的部分字段</td></tr>
<tr><td style="text-align: left;">getNumberResult</td><td>统计查询,用于查询字段的总和、最大值、平均值等数据</td></tr>
<tr><td style="text-align: left;">queryColumnXXX<td>单个字段数据查询和字段的统计查询</td></tr>
<tr><td style="text-align: left;">find<td>查找单个对象</td></tr>
<tr><td style="text-align: left;">queryList<td>查询对象的List集合</td></tr>
<tr><td style="text-align: left;">querySheet</td><td>查询对象的Sheet页式集合</td></tr>
<tr><td style="text-align: left;">directXXX<td>直接运行SQL语句用于复杂的关联查询与更新</td></tr>
</table>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以上接口除了directXXX其他都有等同的异步接口。insert、delete、update接口与JPA同名接口用法一样。DataSource提供了丰富的查询接口且有独特的翻页查询功能。每以系列的方法主要重载三类 单个字段过滤、FilterBean过滤和FilterNode过滤。
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<b>过滤条件</b></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterBean、FilterNode对象用于构造过滤条件。FilterBean可以转化为FilterNode。FilterBean主要用于接收外界构建的过滤条件而FilterNode为了构建内部的过滤条件且降低过滤条件变化的耦合性。</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserBean</span> <span class="kd">implements</span> <span class="n">FilterBean</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">int</span> <span class="n">userid</span><span class="o">;</span>
<span class="nd">@FilterColumn</span><span class="o">(</span><span class="n">express</span> <span class="o">=</span> <span class="n">FilterExpress</span><span class="o">.</span><span class="na">LIKE</span><span class="o">)</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">username</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">Range</span> <span class="n">age</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">UserBean</span><span class="o">(</span><span class="kt">int</span> <span class="n">userid</span><span class="o">,</span> <span class="n">String</span> <span class="n">username</span><span class="o">,</span> <span class="n">Range</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">userid</span> <span class="o">=</span> <span class="n">userid</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">username</span> <span class="o">=</span> <span class="n">username</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">age</span> <span class="o">=</span> <span class="n">age</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">/**</span> <span class="n">以下省略getter</span> <span class="n">setter方法</span> <span class="o">*/</span>
<span class="o">}</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nf">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))</span> <span class="o">等价于</span>
<span class="n">FilterNode</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">&quot;userid&quot;</span><span class="o">,</span> <span class="mi">200001</span><span class="o">).</span><span class="na">and</span><span class="o">(</span><span class="s">&quot;username&quot;</span><span class="o">,</span> <span class="n">FilterExpress</span><span class="o">.</span><span class="na">LIKE</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">).</span><span class="na">and</span><span class="o">(</span><span class="s">&quot;age&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="n">Range</span><span class="o">.</span><span class="na">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nf">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))</span> <span class="o">等价于</span> <span class="s">&quot;WHERE userid = 200001 AND username LIKE &#39;%redkale%&#39; AND age BETWEEN 14 AND 36&quot;</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="kc">null</span><span class="o">)</span> <span class="o">等价于</span> <span class="s">&quot;WHERE userid = 200001 AND username LIKE &#39;%redkale%&#39;&quot;</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="kc">null</span><span class="o">)</span> <span class="o">等价于</span> <span class="s">&quot;WHERE username LIKE &#39;%redkale%&#39;&quot;</span>
</pre></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如上定义UserBean过滤条件当非数值类字段值为null、字符串值为空、数值类字段值小于@FilterColumn.least()值(least的默认值为1)都不会构建成过滤条件。@FilterColumn.express根据字段的类型有不同的默认值若字段类型为Collection子类或数组则express默认为FilterExpress.IN若字段类型为Range的子类则express默认为FilterExpress.BETWEEN其他类型则express默认为FilterExpress.EQUAL。默认字段之间是AND关系若想使用OR关系则需要使用@FilterGroup进行标记</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserBean</span> <span class="kd">implements</span> <span class="n">FilterBean</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">int</span> <span class="n">userid</span><span class="o">;</span>
<span class="nd">@FilterGroup</span><span class="o">(</span><span class="s">&quot;[OR]a&quot;</span><span class="o">)</span>
<span class="nd">@FilterColumn</span><span class="o">(</span><span class="n">express</span> <span class="o">=</span> <span class="n">FilterExpress</span><span class="o">.</span><span class="na">LIKE</span><span class="o">)</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">username</span><span class="o">;</span>
<span class="nd">@FilterGroup</span><span class="o">(</span><span class="s">&quot;[OR]a&quot;</span><span class="o">)</span>
<span class="kd">private</span> <span class="n">Range</span> <span class="n">age</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">UserBean</span><span class="o">(</span><span class="kt">int</span> <span class="n">userid</span><span class="o">,</span> <span class="n">String</span> <span class="n">username</span><span class="o">,</span> <span class="n">Range</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">userid</span> <span class="o">=</span> <span class="n">userid</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">username</span> <span class="o">=</span> <span class="n">username</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">age</span> <span class="o">=</span> <span class="n">age</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">/**</span> <span class="n">以下省略getter</span> <span class="n">setter方法</span> <span class="o">*/</span>
<span class="o">}</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nf">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))</span> <span class="o">等价于</span>
<span class="n">FilterNode</span> <span class="n">orNode</span> <span class="o">=</span> <span class="n">FilterNode</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">&quot;username&quot;</span> <span class="o">,</span> <span class="n">FilterExpress</span><span class="o">.</span><span class="na">LIKE</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">).</span><span class="na">or</span><span class="o">(</span><span class="s">&quot;age&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="n">Range</span><span class="o">.</span><span class="na">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">));</span>
<span class="n">FilterNode</span> <span class="n">node</span> <span class="o">=</span> <span class="n">FilterNode</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">&quot;userid&quot;</span><span class="o">,</span> <span class="mi">200001</span><span class="o">).</span><span class="na">and</span><span class="o">(</span><span class="n">orNode</span><span class="o">));</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nf">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))</span> <span class="o">等价于</span> <span class="s">&quot;WHERE userid = 200001 AND (username LIKE &#39;%redkale%&#39; OR age BETWEEN 14 AND 36)&quot;</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">200001</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="kc">null</span><span class="o">)</span> <span class="o">等价于</span> <span class="s">&quot;WHERE userid = 200001 AND username LIKE &#39;%redkale%&#39;&quot;</span>
<span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="kc">null</span><span class="o">)</span> <span class="o">等价于</span> <span class="s">&quot;WHERE username LIKE &#39;%redkale%&#39;&quot;</span>
<span class="n">source</span><span class="o">.</span><span class="na">getNumberResult</span><span class="o">(</span><span class="n">User</span><span class="o">.</span><span class="k">class</span><span class="o">,</span> <span class="n">FilterFunc</span><span class="o">.</span><span class="na">COUNT</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="k">new</span> <span class="nf">UserBean</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="s">&quot;redkale&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nf">IntRange</span><span class="o">(</span><span class="mi">14</span><span class="o">,</span> <span class="mi">36</span><span class="o">))).</span><span class="na">intValue</span><span class="o">()</span> <span class="o">等价于</span>
<span class="s">&quot;SELECT COUNT(*) FROM user WHERE username LIKE &#39;%redkale%&#39; AND age BETWEEN 14 AND 36&quot;</span>
</pre></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如上@FilterGroup 的value 必须是[OR]或者[AND]开头,没有标记@FilterGroup的字段等价于标记了@FilterGroup(value = "[AND]")。[AND]、[OR]后面的字符串为GROUP_NAME默认的GROUP_NAME为空字符串。如上"[OR]a"可以直接使用"[OR]",有多个[OR]或者[AND]则需要加上不同的NAME。</p>
<h3><a id="source_cachesource" class="anchor" href="#" aria-hidden="true"></a>CacheSource 入门</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CacheSource同Memcached类似像一个带有过期功能地Map容器存放key-value数据。常见的使用场景就是存放HTTP的Session信息。Redkale把用户会话信息数据当做业务数据处理而不是接入层的数据。WebSocket的连接态数据也是用CacheSource存储。key为WebSocket的groupidvalue为WebSocket服务端节点的IP地址列表。</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="kd">implements</span> <span class="n">Service</span> <span class="o">{</span>
<span class="c1">//用户简单信息缓存</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">,</span> <span class="n">UserInfo</span><span class="o">&gt;</span> <span class="n">users</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ConcurrentHashMap</span><span class="o">&lt;&gt;();</span>
<span class="c1">//使用CacheSource必须要指明泛型</span>
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">&quot;usersessions&quot;</span><span class="o">)</span>
<span class="kd">protected</span> <span class="n">CacheSource</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Integer</span><span class="o">&gt;</span> <span class="n">sessions</span><span class="o">;</span>
<span class="c1">//登录</span>
<span class="kd">public</span> <span class="n">RetResult</span><span class="o">&lt;</span><span class="n">UserInfo</span><span class="o">&gt;</span> <span class="nf">login</span><span class="o">(</span><span class="n">LoginBean</span> <span class="n">bean</span><span class="o">)</span> <span class="o">{</span> <span class="c1">//bean.sessionid 在接入层进行赋值</span>
<span class="n">UserInfo</span> <span class="n">user</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="c1">// 登陆逻辑 user = ...</span>
<span class="n">users</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">user</span><span class="o">.</span><span class="na">getUserid</span><span class="o">(),</span> <span class="n">user</span><span class="o">);</span>
<span class="n">sessions</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="mi">600</span><span class="o">,</span> <span class="n">bean</span><span class="o">.</span><span class="na">getSessionid</span><span class="o">(),</span> <span class="n">user</span><span class="o">.</span><span class="na">getUserid</span><span class="o">());</span> <span class="c1">//session过期时间设置为10分钟</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">&lt;&gt;(</span><span class="n">user</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">//获取当前用户信息</span>
<span class="kd">public</span> <span class="n">UserInfo</span> <span class="nf">current</span><span class="o">(</span><span class="n">String</span> <span class="n">sessionid</span><span class="o">)</span> <span class="o">{</span> <span class="c1">//给HTTP的BaseServlet用</span>
<span class="n">Integer</span> <span class="n">userid</span> <span class="o">=</span> <span class="n">sessions</span><span class="o">.</span><span class="na">getAndRefresh</span><span class="o">(</span><span class="n">sessionid</span><span class="o">);</span>
<span class="k">return</span> <span class="n">userid</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="n">users</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">userid</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">//注销</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">logout</span><span class="o">(</span><span class="n">String</span> <span class="n">sessionid</span><span class="o">)</span> <span class="o">{</span>
<span class="n">sessions</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">sessionid</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></pre></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以上是个简单的范例用于用户模块存放sessionid。</p>
<h3><a id="source_confxml" href="#" aria-hidden="true"></a>persistence.xml 配置说明</h3>
<div class="highlight"><pre><span class="c">&lt;!-- 其配置算是标准的JPA配置文件的缩略版 --&gt;</span>
<span class="nt">&lt;persistence&gt;</span>
<span class="c">&lt;!-- 系统基本库 --&gt;</span>
<span class="nt">&lt;persistence-unit</span> <span class="na">name=</span><span class="s">&quot;demouser&quot;</span><span class="nt">&gt;</span>
<span class="c">&lt;!-- 为NONE表示不启动缓存@Cacheable 失效; 非NONE值(通常用ALL)表示开启缓存。 --&gt;</span>
<span class="nt">&lt;shared-cache-mode&gt;</span>NONE<span class="nt">&lt;/shared-cache-mode&gt;</span>
<span class="nt">&lt;properties&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.url&quot;</span> <span class="na">value=</span><span class="s">&quot;jdbc:mysql://127.0.0.1:3306/dbuser?characterEncoding=utf8&quot;</span><span class="nt">/&gt;</span>
<span class="c">&lt;!-- </span>
<span class="c"> javax.persistence.jdbc.driver在JPA的值是JDBC驱动Redkale有所不同值应该是javax.sql.DataSource的子类。 </span>
<span class="c"> 为了兼容用户习惯Redkale内置常见JDBC驱动到javax.sql.DataSource的映射关系</span>
<span class="c"> com.mysql.jdbc.Driver —————— com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</span>
<span class="c"> org.mariadb.jdbc.Driver —————— org.mariadb.jdbc.MySQLDataSource</span>
<span class="c"> oracle.jdbc.driver.OracleDriver —————— oracle.jdbc.pool.OracleConnectionPoolDataSource</span>
<span class="c"> com.microsoft.sqlserver.jdbc.SQLServerDriver —————— com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource</span>
<span class="c"> 因此 com.mysql.jdbc.Driver 会被自动转换成 com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</span>
<span class="c"> --&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.driver&quot;</span> <span class="na">value=</span><span class="s">&quot;com.mysql.jdbc.Driver&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.user&quot;</span> <span class="na">value=</span><span class="s">&quot;root&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.password&quot;</span> <span class="na">value=</span><span class="s">&quot;123456&quot;</span><span class="nt">/&gt;</span>
<span class="c">&lt;!-- </span>
<span class="c"> 最大连接数默认值CPU数*16</span>
<span class="c"> &lt;property name=&quot;javax.persistence.connections.limit&quot; value=&quot;32&quot;/&gt;</span>
<span class="c"> --&gt;</span>
<span class="c">&lt;!-- </span>
<span class="c"> 包含的SQL模板相当于反向LIKE不同的JDBC驱动的SQL语句不一样Redkale内置了MySQL、Oracle、Sqlserver的语句</span>
<span class="c"> &lt;property name=&quot;javax.persistence.contain.sqltemplate&quot; value=&quot;LOCATE(${keystr}, ${column}) &gt; 0&quot;/&gt;</span>
<span class="c"> &lt;property name=&quot;javax.persistence.notcontain.sqltemplate&quot; value=&quot;LOCATE(${keystr}, ${column}) = 0&quot;/&gt;</span>
<span class="c"> --&gt;</span>
<span class="nt">&lt;/properties&gt;</span>
<span class="nt">&lt;/persistence-unit&gt;</span>
<span class="c">&lt;!-- IM消息库 --&gt;</span>
<span class="nt">&lt;persistence-unit</span> <span class="na">name=</span><span class="s">&quot;demoim&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;shared-cache-mode&gt;</span>NONE<span class="nt">&lt;/shared-cache-mode&gt;</span>
<span class="nt">&lt;properties&gt;</span>
<span class="c">&lt;!-- jdbc:mysql://127.0.0.1:3306/dbim?autoReconnect=true&amp;amp;autoReconnectForPools=true&amp;amp;characterEncoding=utf8 --&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.url&quot;</span> <span class="na">value=</span><span class="s">&quot;jdbc:mysql://127.0.0.1:3306/dbim?characterEncoding=utf8&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.driver&quot;</span> <span class="na">value=</span><span class="s">&quot;com.mysql.jdbc.Driver&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.user&quot;</span> <span class="na">value=</span><span class="s">&quot;root&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.jdbc.password&quot;</span> <span class="na">value=</span><span class="s">&quot;123456&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/properties&gt;</span>
<span class="nt">&lt;/persistence-unit&gt;</span>
<span class="nt">&lt;/persistence&gt;</span></pre></div>
<footer class="site-footer">
<span class="site-footer-owner">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欢迎加入Redkale QQ群: 527523235</span>
</footer>
</section>
</body>
</html>