码迷,mamicode.com
首页 > 数据库 > 详细

Hibernate 拥有 Mybits 的SQL/HQL特性 (注解、XML两不误)

时间:2016-06-29 13:00:39      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

????第一次写博客。文章有点渣,喜欢就看看,不喜欢路过点个赞。

????效果:直接一条语句多种用法

  1. ????FROM User A
  2. ???WHERE
  3. ???1=1
  4. ???<#if id??>
  5. ??????<#if like??>
  6. ?????????and A.id like ‘%‘||:id||‘%‘
  7. ??????<#else>
  8. ?????????and A.id=:id
  9. ??????</#if>
  10. ???</#if>

????先来原理 HQL/SQL + Freemarker 模版生成查询语句。

????1:把SQL/HQL写在XML。

????2:编写文件扫描器(缺)

????3:读取解释XML

????4:按实体类空间缓存查询语句

????5:直接使用

注意:不要直接复制,先弄懂流程,因为这源于旧版本及测试包来写的,也省略了部分代码,因此包路径有问题。程序也不完整,缺了的自己让大家自己去思考实现。基本上依赖Spring,不依赖Spring注入的可以考虑用代理模式注入(反射/生成字节码(javassist/asm)/CGLIB等)

1:为了方便先定义约束Query.dtd

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!ELEMENT QueryList (Alias*,Query*)>
  3. <!--<!ELEMENT Context (CachePool,Bean*,Intercept*,ScanToPack*,CloneModel)>-->
  4. <!ELEMENT Alias EMPTY><!--别名-->
  5. <!ELEMENT Query (#PCDATA)><!--sql/hql-->
  6. ?
  7. <!--QueryList-->
  8. <!ATTLIST QueryList package CDATA #REQUIRED>
  9. <!--Alias-->
  10. <!ATTLIST Alias name CDATA #REQUIRED><!--实体类全名-->
  11. <!ATTLIST Alias Alias CDATA #REQUIRED><!--SQL/HQL 语句中的实体类别名-->
  12. <!--Query-->
  13. <!ATTLIST Query name CDATA #REQUIRED><!--实体类全名-->
  14. <!ATTLIST Query type (HQL|SQL) #REQUIRED><!--语句类型:HQL/SQL-->
  15. <!ATTLIST Query freemarkFormat (false|true) #REQUIRED><!--是否使用FREEMARK标签格式化-->
  16. <!ATTLIST Query resultType CDATA #IMPLIED><!--实体类全名-->
  17. <!ATTLIST Query Alias (true|false) #REQUIRED><!--是否使用了类别名-->

2:建个实体类user.class

  1. package project.master.user;
  2. //import、getting、setting 省略
  3. @Entity
  4. public class User extends AbstractEntity {
  5. ???private static final long serialVersionUID = 1L;
  6. ???@Id
  7. ???private String id;
  8. ???@Column(unique = true)
  9. ???private String phone;// 用户名(手机号)
  10. ???private String password;
  11. ???private int status;// 帐号状态(锁定、停用、正常)
  12. ???private Date lastLogin;
  13. ???@Column(updatable = false, nullable = false)
  14. ???private Date createDate = new Date();
  15. }

3:建立对应的XML (User.query.xml)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE QueryList SYSTEM "Query.dtd">
  3. <QueryList package="project.master.user.User">
  4. ???<Alias name="project.master.user.User" Alias="User" />
  5. ???<Alias name="project.freehelp.common.entity.Dictionary" Alias="Dictionary" />
  6. ???<Query name="list" type="HQL" freemarkFormat="true" Alias="true">
  7. ??????<![CDATA[
  8. ?????????FROM User A
  9. ?????????WHERE
  10. ?????????1=1
  11. ?????????<#if id??>
  12. ????????????<#if like??>
  13. ???????????????and A.id like ‘%‘||:id||‘%‘
  14. ????????????<#else>
  15. ???????????????and A.id=:id
  16. ????????????</#if>
  17. ?????????</#if>
  18. ?????????<!-- 各字段判断省略 -->
  19. ??????]]>
  20. ???</Query>
  21. ???<Query name="AAX" type="HQL" freemarkFormat="true" Alias="true">
  22. ??????<!--测试 -->
  23. ??????SELECT A.phone,(SELECT D.value FROM Dictionary D WHERE D.id=‘1‘) as xValue FROM User A
  24. ???</Query>
  25. ???<Query name="checkUser" type="HQL" freemarkFormat="false" Alias="true">
  26. ??????SELECT COUNT(1) FROM User A WHERE A.phone=:phone
  27. ???</Query>
  28. ???<Query name="login" type="HQL" freemarkFormat="false" Alias="true">
  29. ???????FROM User A WHERE A.phone=:phone and A.password=:password
  30. ???</Query>
  31. </QueryList>

4:解析缓存XML

  1. package com.cheuks.bin.db.manager;
  2. //import 省略
  3. public class QueryFactory implements QueryType {
  4. ?
  5. ???private final Map<String, Template> FORMAT_XQL = new ConcurrentHashMap<String, Template>();
  6. ???private final Map<String, String> UNFORMAT_XQL = new ConcurrentHashMap<String, String>();
  7. ???private final Configuration freemarkerConfiguration = new Configuration(Configuration.VERSION_2_3_0);
  8. ???private StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
  9. ???private String files;
  10. ???public QueryFactory() {
  11. ??????super();
  12. ??????freemarkerConfiguration.setTemplateLoader(stringTemplateLoader);
  13. ???}
  14. ???public synchronized void put(String name, String XQL, boolean isFormat) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
  15. ??????if (null == name || null == XQL)
  16. ?????????return;
  17. ??????if (isFormat) {
  18. ?????????stringTemplateLoader.putTemplate(name, XQL);
  19. ?????????FORMAT_XQL.put(name, freemarkerConfiguration.getTemplate(name));
  20. ??????} else {
  21. ?????????UNFORMAT_XQL.put(name, XQL);
  22. ??????}
  23. ???}
  24. ?
  25. ???public String getXQL(String name, boolean isFormat, Map<String, Object> params) throws TemplateException, IOException {
  26. ??????// if (!isScan)
  27. ??????// scan();
  28. ??????if (!isFormat)
  29. ?????????return UNFORMAT_XQL.get(name);
  30. ??????Template tp = FORMAT_XQL.get(name);
  31. ??????if (null == tp)
  32. ?????????return null;
  33. ??????StringWriter sw = new StringWriter();
  34. ??????tp.process(params, sw);
  35. ??????return sw.toString();
  36. ???}
  37. ?
  38. ???@SuppressWarnings("restriction")
  39. ???@javax.annotation.PostConstruct
  40. ???private void scan() {
  41. ??????try {
  42. ?????????Set<String> o = null;
  43. ?????????o = Scan.doScan(files);//扫描所有 *.queue.xml
  44. ?????????xmlExplain(o);
  45. ??????} catch (Exception e) {
  46. ?????????e.printStackTrace();
  47. ??????}
  48. ???}
  49. ?
  50. ???public String getFiles() {return files;}
  51. ???public QueryFactory setFiles(String files) {this.files = files; return this;}
  52. ?
  53. ???public void xmlExplain(Set<String> urls) throws ParserConfigurationException, SAXException, IOException {
  54. ??????Iterator<String> it = urls.iterator();
  55. ??????SAXParserFactory factory = SAXParserFactory.newInstance();
  56. ??????SAXParser parser = factory.newSAXParser();
  57. ??????xmlHandler handler = new xmlHandler();
  58. ??????XMLReader xmlReader = parser.getXMLReader();
  59. ??????//读取XML
  60. ??????xmlReader.setEntityResolver(new EntityResolver() {
  61. ?????????public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
  62. ????????????return new InputSource(this.getClass().getClassLoader().getResourceAsStream("dtd/Query.dtd"));
  63. ?????????}
  64. ??????});
  65. ??????while (it.hasNext()) {
  66. ?????????String str = it.next();
  67. ?????????InputSource is = new InputSource(Thread.currentThread().getContextClassLoader().getResourceAsStream(str));
  68. ?????????is.setEncoding("utf-8");
  69. ?????????xmlReader.setContentHandler(handler);
  70. ?????????xmlReader.parse(is);
  71. ??????}
  72. ???}
  73. ?
  74. ???class xmlHandler extends DefaultHandler {
  75. ??????// private boolean isHQL = false;
  76. ??????private boolean format = false;
  77. ??????private boolean alias = false;
  78. ??????private String packageName = null;
  79. ??????private String name = null;
  80. ??????Map<String, String> aliases = new HashMap<String, String>();
  81. ??????private String value;
  82. ?
  83. ??????@Override
  84. ??????public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  85. ?????????if (qName.equals(QUERY_LIST)) {
  86. ????????????packageName = attributes.getValue(PACKAGE);
  87. ?????????} else if (qName.equals(QUERY)) {
  88. ????????????// isHQL = attributes.getValue(TYPE).equals("HQL");
  89. ????????????name = attributes.getValue(NAME);
  90. ????????????format = Boolean.valueOf(attributes.getValue(FREEMARK_FORMAT));
  91. ????????????alias = Boolean.valueOf(attributes.getValue(ALIAS));
  92. ?????????} else if (qName.equals(ALIAS)) {
  93. ????????????aliases.put(attributes.getValue(ALIAS), attributes.getValue(NAME));
  94. ?????????}
  95. ?????????super.startElement(uri, localName, qName, attributes);
  96. ??????}
  97. ?
  98. ??????@Override
  99. ??????public void characters(char[] ch, int start, int length) throws SAXException {
  100. ?????????value = new String(ch, start, length).replaceAll("(\n|\t)", "");
  101. ?????????if (value.length() > 0) {
  102. ????????????try {
  103. ???????????????put(String.format("%s.%s", packageName, name).toLowerCase(), alias ? alias(value) : value, format);//生成缓存
  104. ????????????} catch (Exception e) {
  105. ????????????}
  106. ?????????}
  107. ?
  108. ??????}
  109. ?
  110. ??????private String alias(String str) {
  111. ?????????if (alias)
  112. ????????????for (Entry<String, String> en : aliases.entrySet())
  113. ???????????????str = str.replaceAll(en.getKey(), en.getValue());
  114. ?????????return str;
  115. ??????}
  116. ?
  117. ???}
  118. }

?

5:定义 DBAdapter接口。

  1. ????public interface DBAdapter {
  2. ?
  3. ???public DBAdapter setSessionFactory(String name);
  4. ?
  5. ???public <T> List<T> getList(Class<?> c) throws Throwable;
  6. ?
  7. ???/***
  8. ????* query模板查询
  9. ????*/
  10. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, boolean isFormat, Map<String, Object> params) throws Throwable;
  11. ?
  12. ???/***
  13. ????* 模板查询
  14. ????*/
  15. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, Object... params) throws Throwable;
  16. ?
  17. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, int page, int size, Object... params) throws Throwable;
  18. ?
  19. ???/***
  20. ????* query模板查询 * @param queryName 查询语句名
  21. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, boolean isFormat, Map<String, Object> params, int page, int size) throws Throwable;
  22. ?
  23. ???public String queryNameFormat(Class<?> entry, String queryName);
  24. }

6:写实现(AbstractHibernateDBAdapterHibernateSingleDBAdapter)

AbstractHibernateDBAdapter

  1. package com.cheuks.bin.db.manager;
  2. @SuppressWarnings({ "rawtypes", "unchecked" })
  3. public abstract class AbstractHibernateDBAdapter implements DBAdapter {
  4. ?
  5. ???private QueryFactory queryFactory;
  6. ?
  7. ???public abstract Session getSession();
  8. ?
  9. ???public <T> List<T> getList(Class<?> c) throws Throwable {
  10. ??????return getList(c, -1, -1);
  11. ???}
  12. ?
  13. ???public <T> List<T> getList(Class<?> c, int page, int size) throws Throwable {
  14. ??????Query query = getSession().createQuery(String.format("FROM %s a", c.getSimpleName()));
  15. ??????List list = page > 0 ? page(query, page, size).list() : query.list();
  16. ??????return null == list ? null : list;
  17. ???}
  18. ?
  19. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, Object... params) throws Throwable {
  20. ??????return getListByXqlQueryName(queryName, isHQL, -1, -1, params);
  21. ???}
  22. ?
  23. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, int page, int size, Object... params) throws Throwable {
  24. ??????String xql = queryFactory.getXQL(queryName, false, null);
  25. ??????Query query = fillParams(isHQL ? getSession().createQuery(xql) : getSession().createSQLQuery(xql), params);
  26. ??????List list = page > 0 ? page(query, page, size).list() : query.list();
  27. ??????return null == list ? null : list;
  28. ???}
  29. ?
  30. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, boolean isFormat, Map<String, Object> params) throws Throwable {
  31. ??????return getListByXqlQueryName(queryName, isHQL, isFormat, params, -1, -1);
  32. ???}
  33. ?
  34. ???public <T> List<T> getListByXqlQueryName(String queryName, boolean isHQL, boolean isFormat, Map<String, Object> params, int page, int size) throws Throwable {
  35. ??????String xql = queryFactory.getXQL(queryName, isFormat, params);
  36. ??????Query query = fillParams(isHQL ? getSession().createQuery(xql) : getSession().createSQLQuery(xql), params);
  37. ??????List list = page > 0 ? page(query, page, size).list() : query.list();
  38. ??????return null == list ? null : list;
  39. ???}
  40. ?
  41. ???protected Query fillParams(Query q, Object... o) {
  42. ??????if (null == o || null == q) {
  43. ?????????return q;
  44. ??????}
  45. ??????for (int i = 0, len = o.length; i < len; i++) {
  46. ?????????q.setParameter(i, o[i]);
  47. ??????}
  48. ??????return q;
  49. ???}
  50. ?
  51. ???protected Query fillParams(Query q, Map<String, ?> o) {
  52. ??????if (null == o || null == q) {
  53. ?????????return q;
  54. ??????}
  55. ??????for (Entry<String, ?> en : o.entrySet())
  56. ?????????try {
  57. ????????????q.setParameter(en.getKey(), en.getValue());
  58. ?????????} catch (Exception e) {
  59. ?????????}
  60. ??????return q;
  61. ???}
  62. ?
  63. ???protected Query page(Query q, int pageNum, int size) {
  64. ??????if (pageNum >= 0 && size >= 0) {
  65. ?????????q.setFirstResult(size * (pageNum - 1));
  66. ?????????q.setMaxResults(size);
  67. ??????}
  68. ??????return q;
  69. ???}
  70. ?
  71. ???public String queryNameFormat(Class<?> entry, String queryName) {
  72. ??????return String.format("%s.%s", entry.getName(), queryName).toLowerCase();
  73. ???}
  74. ?
  75. ???public QueryFactory getQueryFactory() {
  76. ??????return queryFactory;
  77. ???}
  78. ?
  79. ???public AbstractHibernateDBAdapter setQueryFactory(QueryFactory queryFactory) {
  80. ??????this.queryFactory = queryFactory;
  81. ??????return this;
  82. ???}
  83. }

?

HibernateSingleDBAdapter

  1. package com.cheuks.bin.db.manager;
  2. ?
  3. public class HibernateSingleDBAdapter extends AbstractHibernateDBAdapter {
  4. ???//待注入 sessionFactory
  5. ???private SessionFactory sessionFactory;
  6. ???public HibernateSingleDBAdapter setSessionFactory(String name) {
  7. ??????return this;
  8. ???}
  9. ???@Override
  10. ???public Session getSession() {
  11. ??????return sessionFactory.getCurrentSession();
  12. ???}
  13. ???public SessionFactory getSessionFactory() {
  14. ??????return sessionFactory;
  15. ???}
  16. ???public HibernateSingleDBAdapter setSessionFactory(SessionFactory sessionFactory) {
  17. ??????this.sessionFactory = sessionFactory;
  18. ??????return this;
  19. ???}
  20. }

?

7:注入xml

????<!-- QueryFile 注入 -->

????<bean id="queryFactory" class="com.cheuks.bin.db.manager.QueryFactory">

????????<property name="files" value="*.query.xml" />

????</bean>

????<!--Single DBAdapter 注入 -->

????<bean id="dBAdapter" class="com.cheuks.bin.db.manager.HibernateSingleDBAdapter">

????????<property name="sessionFactory" ref="sessionFactory" />

????????<property name="queryFactory" ref="queryFactory" />

????</bean>

?

?

8:使用 AbstractDao 、UserDao

AbstractDao

  1. package com.cheuks.bin.db.manager.dao;
  2. public abstract class AbstractDao<entity, ID extends Serializable> implements BaseDao<entity, ID> {
  3. ?
  4. ???public abstract Class<entity> getEntityClass();
  5. ?
  6. ???public abstract DBAdapter getDBAdapter();
  7. ?
  8. ???public List<entity> getList(int page, int size) throws Throwable {
  9. ??????return getDBAdapter().getList(getEntityClass(), page, size);
  10. ???}
  11. ?
  12. ???public List<entity> getList(Map<String, Object> params, int page, int size) throws Throwable {
  13. ??????return getDBAdapter().getListByXqlQueryName(getDBAdapter().queryNameFormat(getEntityClass(), "list"), true, true, params, page, size);
  14. ???}
  15. ?
  16. ???public <T> List<T> getList(String queryName, Map<String, Object> params, boolean isFromat, int page, int size) throws Throwable {
  17. ??????return getDBAdapter().getListByXqlQueryName(getDBAdapter().queryNameFormat(getEntityClass(), queryName), true, isFromat, params, page, size);
  18. ???}
  19. ?
  20. ???public <T> List<T> getListCustomQueryName(String queryName, Map<String, Object> params, boolean isFromat, int page, int size) throws Throwable { return getDBAdapter().getListByXqlQueryName(queryName.toLowerCase(), true, isFromat, params, page, size);
  21. ???}
  22. ?
  23. ???public List<entity> getListEntity(String queryName, Map<String, Object> params, boolean isFromat, int page, int size) throws Throwable {
  24. ??????return getDBAdapter().getListByXqlQueryName(getDBAdapter().queryNameFormat(getEntityClass(), queryName), true, isFromat, params, page, size);
  25. ???}
  26. ?
  27. ???public List<entity> getListEntityCustomQueryName(String queryName, Map<String, Object> params, boolean isFromat, int page, int size) throws Throwable {
  28. ??????return getDBAdapter().getListByXqlQueryName(queryName.toLowerCase(), true, isFromat, params, page, size);
  29. ???}
  30. }

UserDao

  1. package project.freehelp.common.dao.impl;
  2. @Component
  3. public class UserInfoDaoImpl extends AbstractDao<UserInfo, String> implements UserInfoDao {
  4. ???@Autowired
  5. ???private DBAdapter dBAdapter;
  6. ???@Override
  7. ???public Class<UserInfo> getEntityClass() {
  8. ??????return UserInfo.class;
  9. ???}
  10. ???@Override
  11. ???public DBAdapter getDBAdapter() {
  12. ??????return dBAdapter;
  13. ???}
  14. }

?

整体就完了。XML部分看DTD。觉得不错可以收藏。但请不要 不名字改了变成自己的成果呀!

Hibernate 拥有 Mybits 的SQL/HQL特性 (注解、XML两不误)

标签:

原文地址:http://www.cnblogs.com/cheuks/p/5626264.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!