zoukankan      html  css  js  c++  java
  • .NET C#到Java没那么难,DB篇

    前言

    .NET C#到Java没那么难,都是面向对象的语言,而且语法还是相似的,先对比一下开发环境,再到Servlet,再到MVC,都是一样一样的,只是JAVA的配制项比较多而已,只要配好一个,后面都是copy,简直so easy,而且用myeclipse可以省一些配制

    Java与.NET的区别不在它们的本身,最大的区别在于他们背后的力量,相信大家都能感觉得到,我就不多说。

    系列目录

    一、.NET C#Java没那么难,开发环境篇

    二、.NET C#到Java没那么难,Servlet篇

    三、.NET C#到Java没那么难,MVC篇

    四、.NET C#Java没那么难,DB篇

    五、.NET C#Java没那么难,Nosql篇

    六、.NET C#Java没那么难,微服务篇

    七、.NET C#Java没那么难,大数据篇

    .NET C#到Java没那么难,DB篇

     

    目录

    1.ADO.NET 和 JDBC

    2.DBHelper 和 DBUtils

    3.EF 和 Hibernate

    4.Dapper 和 Mybatis

    1.ADO.NET 和 JDBC

    (1).ADO.NET和JDBC数据库对象

    ADO.NET

    JDBC

    Connection

    Connection

    Command、DataAdapter

    Statement、PreparedStatement

    DataReader 在线数据集

    ResultSet

    DataTable、DataSet  离线数据集

    RowSet

    Transaction

    Transaction

    (2)ADO.NET连接字符串 和 JDBC数据库驱动和Url

    1.ADO.NET各种数据库连接字符串

    2.JDBC数据库驱动和Url

    数据库

    驱动类名

    URL格式

    Oracle

    oracle.jdbc.driver.OracleDriver

    jdbc:oracle:thin:@hostip:1521:dbname

    Sybase

    com.sybase.jdbc2.jdbc.SybDriver

    jdbc:sybase:Tds:hostip:4100/dbname

    Mysql

    com.mysql.jdbc.Driver

    jdbc:mysql://hostip:3306/dbname?useUnicode=true&characterEncoding=GBK

    SQLServer 2000

    com.microsoft.jdbc.sqlserver.SQLServerDriver

    jdbc:microsoft:sqlserver://hostip:1433;DatabaseName=dbname

    SQLServer 2005

    com.microsoft.sqlserver.jdbc.SQLServerDriver

    jdbc:sqlserver://hostip:1433;DatabaseName=dbname

    SQLServer 7.0

    net.sourceforge.jtds.jdbc.Driver

    jdbc:jtds:sqlserver://hostip:1433/dbname

    DB2

    com.ibm.db2.jcc.DB2Driver

    jdbc:db2://hostip:50000/dbname

    Informix

    com.informix.jdbc.IfxDriver

    jdbc:informix-sqli://hostip:port/dbname:informixserver=<dbservername>

    (3).总结

    1.ADO.NET最大的优点是对断开连接访问数据库方式的强有力支持。相比起来,JDBC也引入类似的功能,RowSet,但是比起ADO.NET来,还是不够。

    2.ADO.NET不包括分布式事务的接口,ADO.NET的分布式事务是通过MS DTC统一管理的。JDBC本身就提供了对分布式事务支持的接口,不同的JDBC Driver实现了这一个接口,就支持分布式事务了。

    3.ADO.NET中,不同的ADO .NET Provider的参数格式不一样的。OleDb和Odbc都是使用匿名参数,SqlClient使用“@”开头的命名参数,OracleCLient使用“:”开头的命名参数

    4.JDBC中,参数计数是从1开始的,最初使用者容易犯错。ADO.NET没有此问题

    5.ADO.NET是从ODBC,JDBC,OLEDB 发展过来,而JDBC是ODBC的JAVA版本

    6.ADO.NET封装程度比较高,用起来很方便

    代码对比

    2.DBHelper 和 DBUtils

    DBHelper有动软的SQLHelper,DbProviderFactory封装的DBHelper,微软EnterpriseLibary封装的DBHelper
    主要是封装的ADO.NET的代码,简化dal层的操作
    支持多种数据库,需要自己反射把DataTable转换成Model

    Dbutils由Apache公司开发
    主要是封装了JDBC的代码,简化dao层的操作,有对象映射的功能。
    支持多种数据库,可以直接把数据转换成Model

    源码预览

     1 public Boolean Register(TUser user) throws SQLException{
     2         Connection conn =JDBCUtil.getConnection();
     3         QueryRunner qr = new QueryRunner(); 
     4         String sql="insert into t_user(username,password,sex,birthdate,address) values(?,?,?,?,?)";
     5         
     6         try {
     7             int i = qr.update(conn, sql,user.getUsername(),user.getPassword(),user.getSex(),user.getBirthdate(),user.getAddress());
     8             return i==1 ? true:false;
     9         } catch (SQLException e) {
    10             // TODO Auto-generated catch block
    11             e.printStackTrace();
    12         }
    13         finally{
    14             DbUtils.close(conn);
    15         }
    16         return false;
    17     }
    18 
    19     public List<TUser> findAll() throws SQLException{
    20         Connection conn =JDBCUtil.getConnection();
    21         QueryRunner qr = new QueryRunner(); 
    22         String sql = "select * from T_User";
    23         List<TUser> users = new ArrayList<TUser>();
    24         try {
    25             users = qr.query(conn,sql, new BeanListHandler<TUser>(TUser.class));
    26         } catch (SQLException e) {
    27             // TODO Auto-generated catch block
    28             e.printStackTrace();
    29         }
    30         finally{
    31             DbUtils.close(conn);
    32         }
    33         return users;
    34     }
    View Code

    源码下载

    3.EF 和 Hibernate

    (1).对象关系配制

    EF支持Fluent API和Attribute方式

    Hibernate支持XML和注解的方式 

    (2).Linq 和 HQL,Criteria  面向对象的查询方法

    Linq相比于HQL更强大,支持编译时排错,有智能提示;Criteria相当于Where,Select 等各种方法

    (3).原生SQL支持

    EF:context.Database.SqlQuery() 

    Hibernate:getSession().createSQLQuery()

    (4).缓存

    一级缓存:EF和Hibernate都默认支持一级缓存

    二级缓存:Hibernate支持二级缓存,一般使用Nosql来代替二级缓存

    (5).更新部分字段

    EF:

    先让EF跟踪实体,然后修改实体即可

    EntityEntry<News> entry = cnotext.Entry<News>(news);  

    entry.State = EntityState.Unchanged;  

    entry.Property(t => t.xxxx).IsModified = true; //设置要更新的属性  

    context.SaveChanges(); 

    Hibernate:

    1.使用HQL语句,因为实体字段没有状态

    2.修改hbm的class 的dynamic-update="true",在dao先find出来,再修改保存,影响性能

    更新部分字段的方法

    (6).主从级联保存

    EF和Hibernate都支持主从级联保存

    (7).批量更新和删除

    ORM框架在批量数据处理的时候是有弱势。

    ORM是针对某一对象(单个对象)简单的查改删增,不是批量修改、删除,适合用ORM;而对于批量修改、删除,不适合用ORM

    EF:可以使用SQL实现批量更新和删除,context.Database.ExecuteSqlCommand()

    Hibernate:可以使用HQL实现批量更新和删除,getSession().createQuery(hql).executeUpdate()

    (8).附上封装好的Hibernate BaseDao

    package com.rabbit.dao.impl;
    
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    
    import org.hibernate.Hibernate;
    import org.hibernate.LockMode;
    import org.hibernate.SQLQuery;
    import org.hibernate.transform.Transformers;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
    
    import com.rabbit.dao.BaseDao;
    import com.rabbit.dto.Pager;
    import com.rabbit.dto.QueryParam;
    
    
    public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
        private Logger log = LoggerFactory
                .getLogger(this.getClass());
        
        // 实体类类型(由构造方法自动赋值)
        private Class<T> entityClass;
        
        //实体类名(由构造方法自动赋值)
        private String entityName;
    
        // 构造方法,根据实例类自动获取实体类类型
        public BaseDaoImpl() {
            this.entityClass = null;
            Class c = getClass();
            Type t = c.getGenericSuperclass();
            if (t instanceof ParameterizedType) {
                Type[] p = ((ParameterizedType) t).getActualTypeArguments();
                this.entityClass = (Class<T>) p[0];
                this.entityName = entityClass.getSimpleName();
            }
        }
        protected void initDao() {
            // do nothing
        }
    
        /* 
         * 新增数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#save(T)
         */
        @Override
        public Integer save(T transientInstance) {
            log.debug("saving TCategory instance");
            Integer key = null;
            try {
                key = (Integer)getHibernateTemplate().save(transientInstance);
                log.debug("save successful");
            } catch (RuntimeException re) {
                log.error("save failed", re);
                throw re;
            }
            return key;
        }
        
        /* 
         * 更新数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#update(T)
         */
        @Override
        public void update(T transientInstance) {
            log.debug("updating TCategory instance");
            try {
                getHibernateTemplate().update(transientInstance);
                log.debug("update successful");
            } catch (RuntimeException re) {
                log.error("update failed", re);
                throw re;
            }        
        }
    
        /* 
         * 删除数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#delete(T)
         */
        @Override
        public void delete(T persistentInstance) {
            log.debug("deleting TCategory instance");
            try {
                getHibernateTemplate().delete(persistentInstance);
                log.debug("delete successful");
            } catch (RuntimeException re) {
                log.error("delete failed", re);
                throw re;
            }
        }
        
        /* 
         * 根据id删除数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#deleteById(java.lang.Integer)
         */
        @Override
        public void deleteById(Integer id) {
            log.debug("deleting TCategory instance");
            try {
                T instance = (T) findById(id);
                getHibernateTemplate().delete(instance);
                log.debug("delete successful");
            } catch (RuntimeException re) {
                log.error("delete failed", re);
                throw re;
            }
        }
    
        /* 
         * 合并数据,必须有id,会先select查出数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#merge(T)
         */
        @Override
        public T merge(T detachedInstance) {
            log.debug("merging TCategory instance");
            try {
                T result = (T) getHibernateTemplate().merge(
                        detachedInstance);
                log.debug("merge successful");
                return result;
            } catch (RuntimeException re) {
                log.error("merge failed", re);
                throw re;
            }
        }
    
        /* 
         * 更新数据,有id就更新数据,没有就新增
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#saveOrUpdate(T)
         */
        @Override
        public void saveOrUpdate(T instance) {
            log.debug("attaching dirty TCategory instance");
            try {
                getHibernateTemplate().saveOrUpdate(instance);
                log.debug("attach successful");
            } catch (RuntimeException re) {
                log.error("attach failed", re);
                throw re;
            }
        }
        
        /* 
         * 根据id查询数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#findById(java.lang.Integer)
         */
        @Override
        public T findById(Integer id) {
            log.debug("getting TCategory instance with id: " + id);
            try {
                T instance = (T) getHibernateTemplate().get(entityClass, id);
                return instance;
            } catch (RuntimeException re) {
                log.error("get failed", re);
                throw re;
            }
        }
    
        /* 
         * 根据Model查询数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#findByExample(T)
         */
        @Override
        public List findByExample(T instance) {
            log.debug("finding TCategory instance by example");
            try {
                List results = getHibernateTemplate().findByExample(instance);
                log.debug("find by example successful, result size: "
                        + results.size());
                return results;
            } catch (RuntimeException re) {
                log.error("find by example failed", re);
                throw re;
            }
        }
    
        /* 
         * 根据属性查询
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#findByProperty(java.lang.String, java.lang.Object)
         */
        @Override
        public List findByProperty(String propertyName, Object value) {
            log.debug("finding TCategory instance with property: " + propertyName
                    + ", value: " + value);
            try {
                String queryString = "from "+ entityName +" as model where model."
                        + propertyName + "= ?";
                return getHibernateTemplate().find(queryString, value);
            } catch (RuntimeException re) {
                log.error("find by property name failed", re);
                throw re;
            }
        }
        
        /* 
         * 根据HQL where查询
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#findByHQL(java.lang.String, java.lang.Object)
         */
        @Override
        public List findByHQL(String where,Object... para){
            log.debug("finding all TUser instances");
            try {
                String queryString = "from "+ entityClass.getSimpleName() +" "+ where;
                return getHibernateTemplate().find(queryString,para);
            } catch (RuntimeException re) {
                log.error("find all failed", re);
                throw re;
            }
        }
        
        /* 
         * 根据SQL查询分页
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.BaseDao#findBySQL(java.lang.Class, java.lang.String, QueryParam)
         */
        @Override
        public <DTO> Pager<DTO> findBySQL(Class<DTO> type,String sql,QueryParam param) {
            log.debug("finding all TUser instances");
            try {
                //外层包装sql
                String outerSql = "Select %s from (%s) pager";
                String countSql = String.format(outerSql, "Count(1) cnt",sql);
                SQLQuery countQuery = getSession().createSQLQuery(countSql);
                Object[] para = param.getPara();
                //填充参数
                preparePara(countQuery,para);
                countQuery.addScalar("cnt",Hibernate.INTEGER);
                Integer count = (Integer)countQuery.uniqueResult();
                
                Pager<DTO> pager = new Pager<DTO>();
                pager.InitPager(param.getPageIndex(), param.getPageSize(), count);
                List<DTO> items = new ArrayList<DTO>();
                if(param.getPageIndex()<=pager.getTotalPage()){
                    //设置排序
                    if(param.getOrderBy()!=null){
                        sql=sql+" order by " + param.getOrderBy();
                    }
                    SQLQuery query = getSession().createSQLQuery(String.format(outerSql, "*",sql));
                    //填充参数
                    preparePara(query,para);
                    //转换成dto
                    query.setResultTransformer(Transformers.aliasToBean(type));
                    //设置分页
                    query.setFirstResult(param.getPageOffset());
                    query.setMaxResults(param.getPageSize());
                    items = query.list();
                }
                
                pager.setItems(items);
                
                return pager;
                
            } catch (RuntimeException re) {
                log.error("find all failed", re);
                throw re;
            }
        }
        
        /*
         * 准备Query参数
         */
        private void preparePara(SQLQuery query,Object[] para){
            if(para!=null){
                for(int i=0;i<para.length;i++){
                    query.setParameter(i, para[i]);
                }
            }
        }
        
        /*
         * 准备Query参数
         */
        private void  preparePara(SQLQuery query,Map<String,Object> para){
            if(para!=null && !para.isEmpty()){
                for(String key : para.keySet()){
                    Object obj = para.get(key);
                    if (obj instanceof Collection<?>)
                        query.setParameterList(key, (Collection<?>) obj);
                    else if (obj instanceof Object[])
                        query.setParameterList(key, (Object[]) obj);
                    else
                        query.setParameter(key, obj);        
                }
            }
        }
        
        /* 
         * 查询所有数据
         */
        /* (non-Javadoc)
         * @see com.rabbit.dao.impl.BaseDao#findAll()
         */
        @Override
        public List findAll() {
            log.debug("finding all TCategory instances");
            try {
                String queryString = "from "+entityClass.getSimpleName();
                return getHibernateTemplate().find(queryString);
            } catch (RuntimeException re) {
                log.error("find all failed", re);
                throw re;
            }
        }
    
    }
    BaoDao

    (9).源码下载

    4.扩展阅读

    Hibernate的10个常见面试问题及答案

    update 和 merge、saveOrUpdate的区别

    Dapper和Mybatis的比较放在下一篇吧,也许直接到微服务篇了

    时间仓促,很多东西没有写到,欢迎大家指点

    未完,待续,欢迎评论拍砖

  • 相关阅读:
    random模块
    时间模块
    内置函数
    装饰器函数
    python基础二
    linux Ubuntu 16.04安装 postgresql
    Winfrom中的几种传值方式
    C#6.0新特性
    Treeview显示磁盘下的文件,并且可操作
    C#,ASP.NET简单的MD5加密,解密
  • 原文地址:https://www.cnblogs.com/rabbityi/p/7132789.html
Copyright © 2011-2022 走看看