データベースの設計がコード言語と完全に一致していない場合があります。たとえば、BeetlSQL では、コードの名前 Pojo がデータベースの各テーブルの前に追加されます。 BeetlSQL には DefaultNameConversion、UnderlinedNameConversion、JPANameConversion などの組み込みコンバータがあり、基本的にほとんどの要件を満たすことができます。
前書き
この記事の内容を理解するには、まず、中国人の @Xian が苦労して構築した Java テンプレート エンジンとフル機能の Java データベース Dao という 2 つのプロジェクトを理解する必要があります。 ·Dafu、そして現在、公式は市場のさまざまな主流MVCフレームワークとBeetlとBeetlSQLの統合ソリューションを提供しています
BeetlがJSP、FreeMarker、Velocityなどのいくつかの有名なテンプレートエンジンよりもどのように優れているかはあえて言いません。 、ただし、私の個人的な意見として言いたいのですが、比較のために、Beetl がそれらよりも劣ることは決してなく、BeetlSQL が Hibernate や MyBatis よりも劣ることはありません。Beetl と BeetlSQL について詳しく知りたい場合は、次のリンクを参照してください。詳細については Beetl 公式フォーラムをご覧ください。
ビートルに自分自身でビートルを証明する機会を与えて、学び、働く機会を与えてみてはいかがでしょうか。もしかしたら、あなたも私のように偶然ビートルに夢中になってしまうかもしれません。
テキスト
この記事では、BeetlSQL を使用して Pojo オブジェクトを自動的に生成するときに、カスタム コンバーターを介してマッピング テーブル名のプレフィックスを削除する問題について説明します。
まず一連の開発状況を見てみましょう:
現在、プロジェクト beetl があり、データベースを設計するときに、すべてのテーブル名にプロジェクト接頭辞 bt_ が付いているとします。つまり、すべてのテーブルは bt_user、bt_role など、bt_ で始まります。 、bt_user_role、このようなテーブル名の設計を見たとき、最初に思いつくのは、UnderlinedNameConversion を使用して変換することです。
私と同じように、そのような名前付けを受け入れることができない人は多いと思います。そのため、変換のために NameConversion を自分で定義し、Table が Pojo を生成するときに自動的に追加される Bt プレフィックスを削除する必要があります NameConversion のコア メソッド getPropertyName と getColName、 getTableName、 getClassName は、メソッド名とパラメーターに基づいて理解するのが簡単ですしたがって、テーブル名をクラス名とクラスに変換するメソッドを再実装するために、実際のニーズに応じて NameConversion を再実装するだけで済みます。次のように名前をテーブル名に変換します。
具体的なメソッド: まず、DefaultNameConversion クラスを継承する新しいクラスを作成し、getClassName メソッドと getTableName メソッドをそれぞれオーバーライドし、最後にプロジェクトに記述した Conversion を有効にします
@Override
@Overridepublic String getTableName(Class<?> c) { //遵循BeetlSQL规范,@Table拥有最高优先级 Table table = (Table)c.getAnnotation(Table.class); if(table!=null){ return table.name(); } //UserRole -> user_role String tableName = StringKit.enCodeUnderlined(c.getSimpleName()); //user_role -> bt_user_role return "bt_"+tableName; }@Overridepublic String getClassName(String tableName){ //假定所有表都是以bt_开头 //bt_user_role -> user_role tableName = tableName.substring(tableName.indexOf("_")+1); //user_role -> userRole String clsName = StringKit.deCodeUnderlined(tableName); //userRole -> UserRole return StringKit.toUpperCaseFirstOne(clsName); }
それは裏目に出ました! ! ! 多くの場合、開発で遭遇する可能性のある一連の状況を見てみましょう:
現在、いくつかのユーザー データ テーブル (ユーザーなど) とバックグラウンド管理データ テーブル (管理者など) を含むプロジェクトがあります。ユーザーとバックエンド (City など) の間で以前に共有されていたデータ テーブルは、開発中に区別するために、異なる機能モジュールのテーブルに異なるプレフィックスが追加されました。最終的に、テーブル名は usr_user になります。 、mgr_adminとbase_city このとき、上記の方法でプレフィックスを一律に削除してからプレフィックスを追加すると、やはりプレフィックスが異なり、プレフィックスを削除した後に直接復元することは困難です。
最初にこの問題に遭遇したとき、私の最初のアイデアは、プレフィックスを削除してすべての Pojo (例の usr_user、mgr_admin、base_city など) に @Table アノテーションを自動的に追加することで、最終的にテーブルを生成することでした。次の形式:
理想是丰满的,现实是骨感的。在QQ上与作者沟通遇到这种情况时的解决方案时发现可能会出现这样的情况: 前台用户使用的数据表可能是 usr_user,而后台管理员也属于用户呀,因此可能后台管理员的数据表为mgr_user,最后这样会导致两个类冲突了,生成代码的时候可能会被覆盖一个类,是有问题的。好在机智如我~遇到这样的根据功能模块给不同的表加上不同的前缀,我们在Java程序开发时也经常会使用不同的包名来区分不同的模块,我可以将不同前缀的实体放到对应的包下面,还原表名的时候读取一下包名即可反向解析出表名,下面是我的具体实现:
@Overridepublic String getClassName(String tableName){ //为了安全起见,做了个判断,理论上项目数据库设计好了应该是无需判断直接截取所有前缀 //usr_user_role -> user_role if(tableName.matches("^(usr_|base_|mgr_).*")){ tableName = tableName.substring(tableName.indexOf("_")+1); } //user_role -> UserRole String clsName = StringKit.deCodeUnderlined(tableName); return StringKit.toUpperCaseFirstOne(clsName); }@Overridepublic String getTableName(Class<?> c) { Table table = (Table)c.getAnnotation(Table.class); if(table!=null){ return table.name(); } //获取Package 最后一层 xxx.pojo.usr -> Usr String pkg = c.getPackage().getName(); pkg = pkg.substring(pkg.lastIndexOf(".")+1); pkg = Character.toUpperCase(pkg.charAt(0))+pkg.substring(1); //Usr+User -> UsrUser -> usr_user return StringKit.enCodeUnderlined(pkg+c.getSimpleName()); }
然后在使用BeetlSQL反向生成Pojo的时候,使用Filter将数据表分门别类的生成到不同的包下面
//记得初始化SQLManager时要使用自己写好的NameConvertionSQLManager sql = initSQLManager(); GenConfig config = new GenConfig(); sql.genALL("xxxx.pojo.usr", config, new GenFilter(){ @Override public boolean accept(String tableName) { return tableName.startsWith("usr_"); } }); sql.genALL("xxxx.pojo.mgr", config, new GenFilter(){ @Override public boolean accept(String tableName) { return tableName.startsWith("mgr_"); } }); sql.genALL("xxxx.pojo.base", config, new GenFilter(){ @Override public boolean accept(String tableName) { return tableName.startsWith("base_"); } });
最终会在项目中会生成以下Pojo
usr_user -> xxxx.pojo.usr.User.java
mgr_admin -> xxxx.pojo.mgr.Admin.java
base_city -> xxxx.pojo.base.City.java
即便是有类名冲突的,因为在不同的包下,所以也不会影响
就这样一次轻松而又愉快的BeetlSQL自定义去除Pojo和表前缀被解决啦~
最后
之前所有项目的开发都是Jsp,几乎没使用过其他第三方模板库,因为一次误打误撞让我认识了Beetl,它的轻巧,它独特的语法都深深的吸引了我,因为Beetl又让我认识了BeetlSQL,抱着试一试的心态尝试过之后总有一种把当前项目(使用的Hibernate)推倒重来的冲动,虽然最后因为项目的工程量和工期原因,当前的这个项目最终还是使用了Hibernate,但是我可以确定的是,在以后的开发道路上,如果允许,如果没有能让我更心动的通用Dao,BeetlSQL将会是我不二的选择。
今天在这里分享这篇自定义NameConvertion的功能,其实并没有多少技术含量,更多的是想做一次简单的推广,让更多人知道Beetl,让更多人爱上Beetl~