??xml version="1.0" encoding="utf-8" standalone="yes"?> 专注于分享Java后端相关技术、老司机实战干货,不限于JVM、ƈ发、设计模式、性能优化、分布式&微服务、云原生、大数据相关主题?/span> 软gpȝ的ƈ发控制一般是通过加锁Q有乐观锁和悲观锁两U)来实玎ͼ乐观锁是一U事后补救措施,是通过E序的逻辑控制版本来实现的Q而悲观锁是事前的一U预防措施,它利用数据库的锁机制来实现?/p>
虽然乐观锁能够提高系l的性能Q但它是对发生冲H的讉Kq行事后的补救,应用在用戯入数据量很少的场合比较适合Q但如果在企?a class="infotextkey" target="_blank">ERPQ用户与pȝ交互涉及大量数据在页面表单上录入Q如果事后提交失败后才提C用戯重新录入是很不现实的Q所以有必要q行事前控制Q这p采用悲观锁?br />
一个典型的倚赖数据库的悲观锁调用: q条 sql 语句锁定?account 表中所有符合检索条Ӟname=”Erica”Q的记录。本ơ事务提交之前(事务提交时会释放事务q程中的锁)Q外界无法修改这些记录。Hibernate 的悲观锁Q也是基于数据库的锁机制实现?br />
下面的代码实CҎ询记录的加锁Q?br />
String hqlStr ="from TUser as user where user.name='John'";
Java爱好者社?/strong>
公众号内容简介:
希望x的你停下脚步Q定有所收获?/span>
以前的个人博客内容不好迁U,所以我打算Ҏ自己的多q经验,不断整理输出有h值的内容?br />目前公众号内Ҏ关于SpringCloudQ微服务框架Q、SkywalkingQAPM监控调用链)、JVMQGC分析、内存泄漏分析)、ƈ发编E?/span>相关原创实战文章已出炉?br />
最q刚开始已l有不少伙伴关注了Q期待能有幸搜烦到本博客的同学,可以扫码x一下,不胜感激?br />大家有Q何技术、职场、面试上的问题都可以与我交流?br />
方式一Q?/strong>扫码以下公众号二l码Q?/strong>
方式二:在微信上直接搜烦Q?nbsp;javatech_cbo
感谢各位伙伴的支持Q后l会在该公众号上输出大量的有价值的实战q货 Q期待与你一同进步与成长?br />
]]>
需求是查询|络信息Q网l信息中兌了分区、网lIP(1个网l-QN个网lテQ?Q网桥信?
HQLQ?br />
StringBuffer hql = new StringBuffer();
hql.append("select new Map(vn.id as id, vn.vnName as vnName, b.name as vnType, ");
hql.append("vn.vnIptype as vnIptype, vn.vnIp as vnIp,vn.vnNat as vnNat, vn.vnFlag as vnFlag, ");
hql.append("vn.vnetFlag as vnetFlag, (case when sum(vmvn.state)='0' then 0 else 1 end) as vnState, ");
hql.append("vn.useType as useType, vn.createTime as createTime, ");
hql .append("zone.oneName as oneName, zone.oneHypervisor as oneHypervisor, zone.oneSeq as oneSeq) ");
hql.append("from VnetTable vn, ZoneTable zone, BridgeTable b ");
hql.append("left join fetch vn.VnTables vmvn where zone.id = vn.zoneId and vn.vnType = b.id ");
... ...
hql.append(" group by vn.id");
if (vnState != null && !"".equals(vnState)) {
if ("0".equals(vnState)) {
hql.append(" having sum(vmvn.state)=0");
} else if ("1".equals(vnState)) {
hql.append(" having sum(vmvn.state)!=0");
}
}
}
hbm配置文gQ?br />
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.base.mapping.VnetTable" table="vnet_table" >
<id name="id" type="java.lang.String">
<column name="ID" length="32" />
<generator class="uuid.hex" />
</id>
<property name="vnId" type="java.lang.Long">
<column name="VN_ID">
<comment>创徏虚拟|络时得到的ID</comment>
</column>
</property>
...
<property name="zoneId" type="java.lang.String">
<column name="ZONE_ID" length="32">
<comment>分区ID</comment>
</column>
</property>
<property name="vlanId" type="java.lang.Integer">
<column name="VLAN_ID">
<comment>VLAN_ID</comment>
</column>
</property>
<set name="vnTables" lazy="false" order-by="id asc" inverse="false" fetch="join" cascade="all">
<key column="VN_NID"/>
<one-to-many class="com.base.mapping.VnTable"/>
</set>
</class>
</hibernate-mapping>
理解inverse和cascadeQ可以参考:http://blog.csdn.net/wkcgy/article/details/6271321
ȝQ?nbsp;
<one-to-many>中,inverse=”true”Q由“many”Ҏq行兌关系的维?nbsp;
<many-to-many>中,只设|其中一方inverse=”false”Q或双方都不讄
CascadeQ通常情况下都不会使用。特别是删除Q一定要慎重?/span>
操作
一般对many-to-one和many-to-many不设|联,q要看业务逻辑的需?对one-to-one和one-to-many讄U联?/span>
many-to-many兌关系中,一端设|inverse=”false”Q另一端设|ؓinverse=”true”。在one-to-many兌关系中,讄inverse=”true”,由多端来l护关系?/span>
]]>
]]>
在多个客L可能d同一W数据或同时更新一W数据的情况下,防止同一个数据被修改而造成混ؕQ最单的手段是在读取时Ҏ据进行锁定,其它客户端不能对同一W数据进行更新的d动作?/p>
select * from account where name=”John” for update
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); // 加锁
List userList = query.list();// 执行查询Q获取数?/font>
query.setLockMode Ҏ询语句中Q特定别名所对应的记录进行加锁(我们为TUser cL定了一个别?“user” Q,q里也就是对q回的所?user 记录q行加锁?br />
观察q行?Hibernate 生成?SQL 语句Q?br />
select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name='John' ) for update
q里 Hibernate 通过使用数据库的 for update 子句实现了悲观锁机制?br />
Hibernate 的加锁模式有Q?br />
LockMode.NONE Q?/strong> 无锁机制?br />
LockMode.WRITE Q?/strong> Hibernate ?Insert ?Update 记录的时候会自动获取?br />
LockMode.READ Q?/strong> Hibernate 在读取记录的时候会自动获取?br />
以上q三U锁机制一般由 Hibernate 内部使用Q如 Hibernate Z保证 Updateq程中对象不会被外界修改Q会?save Ҏ实现中自动ؓ目标对象加上 WRITE 锁?br />
LockMode.UPGRADE Q?/strong>利用数据库的 for update 子句加锁?br />
LockMode. UPGRADE_NOWAIT Q?/strong> Oracle 的特定实玎ͼ利用 Oracle ?for update nowait 子句实现加锁?br />
上面q两U锁机制是我们在应用层较为常用的Q加锁一般通过以下Ҏ实现Q?br />
Criteria.setLockMode
Query.setLockMode
Session.lock
注意Q只有在查询开始之前(也就?Hiberate 生成 SQL 之前Q设定加锁,才会真正通过数据库的锁机制进行加锁处理,否则Q数据已l通过不包?for update 子句?Select SQL 加蝲q来Q所谓数据库加锁也就无从谈v?br />
]]>
/* private CertBindView getCertBindView(Certbind view) { import org.apache.log4j.Logger; import com.cns.certservice.exception.DAOException; private HibernateTemplate() { } /** /** /** /** /** /** } /** } /** } /** } /** } /**
]]>
]]>
List<CertInfoListView> liinfo = new ArrayList<CertInfoListView>();
String sql="select b.usercode,b.agentcode,i.sn,i.cert,i.certstate,i.endtime, i.ipasskeyno,b.id,b.addtime from certbind b inner join certinfo i on b.ipasskeyno=i.ipasskeyno";
Session session = HibernateTemplate.getInstance().getSession();
StringBuffer sb = new StringBuffer(sql);
sb.append(" where 1=1 ");
if(!CheckEmpty.isEmpty(view.getIpasskeyno())){
sb.append(" and i.ipasskeyno ='").append(view.getIpasskeyno()).append("'");
}
if(!CheckEmpty.isEmpty(view.getAgentcode())){
sb.append(" and b.agentcode ='").append(view.getAgentcode()).append("'");
}
if(!CheckEmpty.isEmpty(view.getSn())){
sb.append(" and i.sn ='").append(view.getSn()).append("'");
}
if(!CheckEmpty.isEmpty(view.getUsercode())){
sb.append(" and b.usercode ='").append(view.getUsercode()).append("'");
}
if(view.getAddtime()!=null){
sb.append(" and b.addtime=").append(view.getAddtime());
}
sb.append(" order by ipasskeyno ,addtime desc");
Query q = session.createSQLQuery(sb.toString());
int pageno = view.getPageno();
int size = view.getPagesize();
if(pageno!=0&&size!=0){
q.setFirstResult((pageno-1)*size);
q.setMaxResults(size);
}
List list = q.list();
Iterator it = list.iterator();
while(it.hasNext()){
Object[] obj = (Object[])it.next();
CertInfoListView c = new CertInfoListView();
for(int i=0;i<obj.length;i++){
if(!CheckEmpty.isEmpty((String)obj[0])){
c.setUsercode((String)obj[0]);
}
if(!CheckEmpty.isEmpty((String)obj[1])){
c.setAgentcode((String)obj[1]);
}
if(!CheckEmpty.isEmpty((String)obj[2])){
c.setSn((String)obj[2]);
}
if(obj[3]!=null){
SerializableClob sc = (SerializableClob)obj[3];
String cc = null;
if(sc!=null){
try {
cc = sc.getSubString(1, (int)sc.length());
} catch (SQLException e) {
}
}
if(cc!=null)c.setCert(cc);
}
if(obj[4]!=null){
BigDecimal b = (BigDecimal)obj[4];
c.setCertstate(b.intValue());
}
if((obj[5])!=null){
c.setEndtime(((Date)obj[5]));
}
if(!CheckEmpty.isEmpty((String)obj[6])){
c.setIpasskeyno((String)obj[6]);
}
c.setCertbindid(Integer.parseInt((String)obj[7]));
c.setAddtime((Date)obj[8]);
}
liinfo.add(c);
}
if(session!=null&&session.isConnected())session.close();
return liinfo;
}
实现分页的DAO
/*
* (non-Javadoc)
*
* @see com.cns.certservice.dao.CertBindTabDao#getCertBindList(com.cns.certservice.vo.CertBindView)
*/
public List<CertBindView> getCertBindList(CertBindView view)
throws DAOException {
List<CertBindView> li = null;
List<Certbind> lic = null;
Session session = null;
try {
session = HibernateTemplate.getInstance().getSession();
Criteria cri = session.createCriteria(Certbind.class);
Certbind c = getCertBind(view);
if (c.getAddtime() != null) {
cri.add(Expression.eq("addtime", c.getAddtime()));
}
if (!CheckEmpty.isEmpty(c.getAgentcode())) {
cri.add(Expression.eq("agentcode", c.getAgentcode()));
}
if(c.getId()!=0)cri.add(Expression.eq("id", c.getId()));
if (!CheckEmpty.isEmpty(c.getIpasskeyno())) {
cri.add(Expression.eq("ipasskeyno", c.getIpasskeyno()));
}
if (!CheckEmpty.isEmpty(c.getUsercode())) {
cri.add(Expression.eq("usercode", c.getUsercode()));
}
if (!CheckEmpty.isEmpty(c.getExtend1())) {
cri.add(Expression.eq("extend1", c.getExtend1()));
}
if (!CheckEmpty.isEmpty(c.getExtend2())) {
cri.add(Expression.eq("extend2", c.getExtend2()));
}
if (c.getAgenttype() != 0) {
cri.add(Expression.eq("agenttype", c.getAgenttype()));
}
int pageno = view.getPageno();
int size = view.getPagesize();
if(pageno!=0&&size!=0){
cri.setFirstResult((pageno-1)*size);
cri.setMaxResults(size);
}
lic = cri.list();
if (lic != null) {
li = new ArrayList<CertBindView>();
for (Certbind cer : lic) {
CertBindView v = getCertBindView(cer);
li.add(v);
}
}
} catch (HibernateException e) {
log.error(e,e);
throw new DAOException(e);
}finally{
if (session != null && session.isConnected())
session.close();
}
return li;
}
public int getInfoListCount(CertBindView view) throws DAOException {
int count = 0;
Session session = null;
try {
session = HibernateTemplate.getInstance().getSession();
Criteria cri = session.createCriteria(Certbind.class);
Certbind c = getCertBind(view);
if (c.getAddtime() != null) {
cri.add(Expression.eq("addtime", c.getAddtime()));
}
if (!CheckEmpty.isEmpty(c.getAgentcode())) {
cri.add(Expression.eq("agentcode", c.getAgentcode()));
}
if(c.getId()!=0)cri.add(Expression.eq("id", c.getId()));
if (!CheckEmpty.isEmpty(c.getIpasskeyno())) {
cri.add(Expression.eq("ipasskeyno", c.getIpasskeyno()));
}
if (!CheckEmpty.isEmpty(c.getUsercode())) {
cri.add(Expression.eq("usercode", c.getUsercode()));
}
if (!CheckEmpty.isEmpty(c.getExtend1())) {
cri.add(Expression.eq("extend1", c.getExtend1()));
}
if (!CheckEmpty.isEmpty(c.getExtend2())) {
cri.add(Expression.eq("extend2", c.getExtend2()));
}
if (c.getAgenttype() != 0) {
cri.add(Expression.eq("agenttype", c.getAgenttype()));
}
count = (Integer)cri.setProjection(Projections.rowCount()).uniqueResult();
cri.setProjection(null);
} catch (HibernateException e) {
log.error(e,e);
throw new DAOException(e);
}finally{
if (session != null && session.isConnected())
session.close();
}
return count;
}
* (non-Javadoc)
*
* @see com.cns.certservice.dao.CertBindTabDao#updateCertBind(com.cns.certservice.vo.CertBindView)
*/
public boolean updateCertBind(CertBindView view) throws DAOException {
boolean res = false;
if (view.getId()==0) {
throw new DAOException("getId from CertBindView is null!");
}
Session session= null;
try {
session = HibernateTemplate.getInstance().getSession();
Certbind c = (Certbind) session.get(Certbind.class, view.getId());
if (!CheckEmpty.isEmpty(view.getAgentcode()))
c.setAgentcode(view.getAgentcode());
if (!CheckEmpty.isEmpty(view.getExtend1()))
c.setExtend1(view.getExtend1());
if (!CheckEmpty.isEmpty(view.getExtend2()))
c.setExtend2(view.getExtend2());
if (!CheckEmpty.isEmpty(view.getIpasskeyno()))
c.setIpasskeyno(view.getIpasskeyno());
if (!CheckEmpty.isEmpty(view.getUsercode()))
c.setUsercode(view.getUsercode());
if (view.getAgenttype() != 0)
c.setAgenttype(view.getAgenttype());
res = HibernateTemplate.getInstance().updateObject(c);
} catch (HibernateException e) {
log.error(e,e);
throw new DAOException(e);
}finally{
if (session != null && session.isConnected())
session.close();
}
return res;
}
private Certbind getCertBind(CertBindView view) {
Certbind c = new Certbind();
if (view.getAddtime() != null)
c.setAddtime(view.getAddtime());
if (!CheckEmpty.isEmpty(view.getAgentcode()))
c.setAgentcode(view.getAgentcode());
if (!CheckEmpty.isEmpty(view.getExtend1()))
c.setExtend1(view.getExtend1());
if (!CheckEmpty.isEmpty(view.getExtend2()))
c.setExtend2(view.getExtend2());
if (!CheckEmpty.isEmpty(view.getIpasskeyno()))
c.setIpasskeyno(view.getIpasskeyno());
if (!CheckEmpty.isEmpty(view.getUsercode()))
c.setUsercode(view.getUsercode());
if(view.getId()!=0)c.setId(view.getId());
if (view.getAgenttype() != 0)
c.setAgenttype(view.getAgenttype());
return c;
}
CertBindView c = new CertBindView();
if (view.getAddtime() != null)
c.setAddtime(view.getAddtime());
if (!CheckEmpty.isEmpty(view.getAgentcode()))
c.setAgentcode(view.getAgentcode());
if (!CheckEmpty.isEmpty(view.getExtend1()))
c.setExtend1(view.getExtend1());
if (!CheckEmpty.isEmpty(view.getExtend2()))
c.setExtend2(view.getExtend2());
if (!CheckEmpty.isEmpty(view.getIpasskeyno()))
c.setIpasskeyno(view.getIpasskeyno());
if (!CheckEmpty.isEmpty(view.getUsercode()))
c.setUsercode(view.getUsercode());
if(view.getId()!=0)c.setId(view.getId());
if (view.getAgenttype() != 0)
c.setAgenttype(view.getAgenttype());
return c;
}
]]>
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class HibernateTemplate {
* static final session factory
*/
private static SessionFactory sessionFactory = null;
* local thread variable used for storing share session instance
*/
private static final ThreadLocal localSession = new ThreadLocal();
* log4j logger
*/
private static final Logger logger = Logger
.getLogger(HibernateTemplate.class);
/**
* use JTA transaction
*/
/**
* 该工具唯一实例?br />
*/
private static HibernateTemplate instance = null;
private static Transaction tx = null;
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final Configuration cfg = new Configuration();
/** Holds a single instance of Session */
private static final ThreadLocal threadLocal = new ThreadLocal();
* 获取持久工具的唯一实例Q以后不是用单实例模式Q而不是采用对象池支持?br />
* @return PersistentTool
* @throws BaseException
*/
public synchronized static HibernateTemplate getInstance() {
if (instance == null) {
instance = new HibernateTemplate();
instance.initHibernate();
}
return instance;
}
* 实现Hibernate的初始化配置环境?br />
*/
public void initHibernate() {
try {
//此处从系l\径中获取配置文g
cfg.configure(CONFIG_FILE_LOCATION);
} catch (HibernateException ex) {
ex.printStackTrace();
}
try {
// 装蝲配置Q构造SessionFactory对象
sessionFactory = cfg.buildSessionFactory();
} catch (HibernateException e) {
e.printStackTrace();
}
}
* Get the share session
* @
* @return Session share session
*/
public Session getSession() {
logger.debug("Now enter into getSession method of DaoUtil");
//obtain share session
Session session = (Session) localSession.get();
try {
if (session == null||!session.isOpen()) {
//get session by session factory
session = sessionFactory.openSession();
localSession.set(session);
}
} catch (HibernateException ex) {
ex.printStackTrace();
return session;
}
* Close share session
* @
*/
public void close() {
logger.debug("Now enter into closeSessionl");
//obtain share session
Session session = (Session) localSession.get();
localSession.set(null);
if (session != null) {
try {
session.flush();
session.close();
} catch (HibernateException ex) {
ex.printStackTrace();
}
}
* Begin JTA transaction
* @
*/
public void beginTransaction() {
logger.debug("Now enter into beginTransaction");
try {
Session session = (Session) localSession.get();
tx = session.beginTransaction();
} catch (Exception ex) {
ex.printStackTrace();
}
* Commit transaction
* @
*/
public void commitTransaction() {
try {
tx.commit();
} catch (Exception ex) {
ex.printStackTrace();
}
* Rollback transaction when breaching ACID operation
* @
*/
public void rollbackTransaction() {
try {
tx.rollback();
} catch (Exception ex) {
ex.printStackTrace();
}
* Insert a record into table
* @param obj Object
* @throws DAOException
* @
*/
public int insertObject(Object obj) throws DAOException {
int res = 0;
logger.debug("Now enter into insertObject");
//obtain current share session
try {
Session session = HibernateTemplate.getInstance().getSession();
beginTransaction();
Object robj = session.save(obj);
if (robj instanceof Integer) {
res = (Integer) robj;
}
if (robj instanceof String) {
res =1;
}
session.flush();
} catch (HibernateException ex) {
rollbackTransaction();
logger.error("insertObject error:", ex);
throw new DAOException(ex);
} finally {
commitTransaction();
close();
}
return res;
}
/**
* Delete a record of database table by Hibernate po object
* @param obj Object
* @throws DAOException
* @
*/
public boolean deleteObject(Object obj) throws DAOException {
boolean res = false;
logger.debug("Now enter into deleteObject method");
//obtain current share session
try {
Session session = HibernateTemplate.getInstance().getSession();
beginTransaction();
session.delete(obj);
session.flush();
res = true;
} catch (HibernateException ex) {
rollbackTransaction();
logger.error("deleteObject error:", ex);
throw new DAOException(ex);
} finally {
commitTransaction();
close();
}
return res;
}
/**
* Update a record of database table
* @param ob Object
* @throws DAOException
* @
*/
public boolean updateObject(Object ob) throws DAOException {
boolean res = false;
logger.debug("Now enter into updateObject");
//obtain current share session
try {
Session session = HibernateTemplate.getInstance().getSession();
beginTransaction();
session.update(ob);
session.flush();
res= true;
} catch (HibernateException ex) {
rollbackTransaction();
logger.error("updateObject error:", ex);
throw new DAOException(ex);
} finally {
commitTransaction();
close();
}
return res;
}
}
]]>
]]>
]]>