.NET C#到Java沒那麼難,DB篇

前言html

.NET C#到Java沒那麼難,都是面向對象的語言,並且語法仍是類似的,先對比一下開發環境,再到Servlet,再到MVC,都是同樣同樣的,只是JAVA的配製項比較多而已,只要配好一個,後面都是copy,簡直so easy,並且用myeclipse能夠省一些配製java

Java與.NET的區別不在它們的自己,最大的區別在於他們背後的力量,相信你們都能感受獲得,我就很少說。mysql

 

 

系列目錄面試

1、.NET C#Java沒那麼難,開發環境篇spring

2、.NET C#到Java沒那麼難,Servlet篇sql

3、.NET C#到Java沒那麼難,MVC篇數據庫

4、.NET C#Java沒那麼難,DB篇緩存

5、.NET C#Java沒那麼難,Nosql篇oracle

6、.NET C#Java沒那麼難,微服務篇app

7、.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的比較放在下一篇吧,也許直接到微服務篇了

時間倉促,不少東西沒有寫到,歡迎你們指點

未完,待續,歡迎評論拍磚

相關文章
相關標籤/搜索