hibernate基于注解的维护权反转:@OneToMany(mappedBy=)
背景说明:首先是SSH环境下,对象基于注解的方式映射到数据库;
昨天遇到一个比较纠结的问题,@OneToMany(mappedBy="xxx"), mappedBy属性有什么用,然后是写在哪一边?
还有一个问题是:@JoinColumn(name="xxxxx"),JoinColumn有什么用?
先贴出最初的代码:一些基本的注解,在一对多的关系上没有使用JoinColumn和mappedBy属性
部门类:主要是第33、34行
package com.lizhou.entity.test; import java.util.ArrayList;
import java.util.List; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; /**
* 部门:与员工一对多关系
* @author bojiangzhou
*
*/
@Entity
@Table(name="department")
public class Department { @Id
@GeneratedValue(generator="_native")
@GenericGenerator(name="_native", strategy="native")
private int id; //ID @Column(length=20)
private String dname; //部门名称 @OneToMany
private List<Employee> employeeList = new ArrayList<>(); //部门下的员工集合 // get/set方法
}
员工类:主要是第32、33行
package com.lizhou.entity.test; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; /**
* 员工:与部门多对一关系
* @author bojiangzhou
*
*/
@Entity
@Table(name="employee")
public class Employee { @Id
@GeneratedValue(generator="_native")
@GenericGenerator(name="_native", strategy="native")
private int id; //ID @Column(length=20)
private String ename; //员工姓名 @Column(length=20)
private String phone; //电话 @ManyToOne
private Department department; //所属部门 //get/set方法
}
最初的注解配置里,在一对多的关系上,即employeeList和department没有使用JoinColumn。
看下图,employee表会自动添加一个外键列department_id,虽然关系映射上是正确了,但是有一个问题,数据库里多了一张表出来,这不是想要的结果。
解决方法:在employeeList和department字段上加上@JoinColumn注解
@OneToMany
@JoinColumn(name="departmentId")
private List<Employee> employeeList = new ArrayList<>(); //部门下的员工集合
@ManyToOne//
@JoinColumn(name="departmentId")//
private Department department; //所属部门
这样一来的话就只有两张表了,所以在一对多或者一对一的关系下,需要加上@JoinColumn来指定外键列,避免生成一张中间表。
而且经试验,多的一方(Employee)里的department必须加上@JoinColumn,Department里不加不会影响表的结构,不知道会不会有其它影响;
但是如果Employee属于多的一方,如果没有指定外键列,还是会自动生成一个department_id外键列。
接下来讨论mappedBy属性:mappedBy属性主要是针对外键而言。与之相对应的是xml中的inverse属性。
如下是测试类代码:此时还没有设置mappedBy属性,映射时,默认是都由自身维护关联关系。
package com.lizhou.action.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lizhou.entity.test.Department;
import com.lizhou.entity.test.Employee; /**
* 测试类
* @author bojiangzhou
*
*/ public class TestAction { private static SessionFactory sessionFactory = null; static {
//读取classpath中applicationContext.xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取session中配置的sessionFactory对象
sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
} @Test
public void testSave(){
//创建一个部门对象
Department d1 = new Department();
d1.setDname("研发部"); //创建两个员工对象
Employee e1 = new Employee();
e1.setEname("张三");
e1.setPhone("13111111111");
Employee e2 = new Employee();
e2.setEname("李四");
e2.setPhone("18523222222"); //设置对象关联
d1.getEmployeeList().add(e1);
d1.getEmployeeList().add(e2);
e1.setDepartment(d1);
e2.setDepartment(d1); //获取Session
Session session = sessionFactory.openSession();
//开始事务
Transaction t = session.beginTransaction();
try {
//添加数据
session.save(d1);
session.save(e1);
session.save(e2);
//提交事务
t.commit();
} catch (RuntimeException e) {
//有异常则回滚事务
t.rollback();
e.printStackTrace();
} finally {
//关闭session
session.close();
}
} }
执行testSave后,控制台打印如下语句:
Hibernate: insert into department (dname) values (?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: update employee set departmentId=? where id=?
Hibernate: update employee set departmentId=? where id=?
可以看到多了两条update语句,这是因为两边都维护关系,先插入的部门,再插入员工,插入员工时,已经设置好外键了,但部门方也维护关系,会再执行一次更新操作,为员工设置外键,这样就导致多出了两条update语句,这里是有性能损耗的。
一种解决办法是:将第46、47行去掉,即对象上部门不关联员工
package com.lizhou.action.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lizhou.entity.test.Department;
import com.lizhou.entity.test.Employee; /**
* 测试类
* @author bojiangzhou
*
*/ public class TestAction { private static SessionFactory sessionFactory = null; static {
//读取classpath中applicationContext.xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取session中配置的sessionFactory对象
sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
} @Test
public void testSave(){
//创建一个部门对象
Department d1 = new Department();
d1.setDname("研发部"); //创建两个员工对象
Employee e1 = new Employee();
e1.setEname("张三");
e1.setPhone("13111111111");
Employee e2 = new Employee();
e2.setEname("李四");
e2.setPhone("18523222222"); //设置对象关联
// d1.getEmployeeList().add(e1);
// d1.getEmployeeList().add(e2);
e1.setDepartment(d1);
e2.setDepartment(d1); //获取Session
Session session = sessionFactory.openSession();
//开始事务
Transaction t = session.beginTransaction();
try {
//添加数据
session.save(d1);
session.save(e1);
session.save(e2);
//提交事务
t.commit();
} catch (RuntimeException e) {
//有异常则回滚事务
t.rollback();
e.printStackTrace();
} finally {
//关闭session
session.close();
}
} }
Hibernate: insert into department (dname) values (?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
这样部门方就不会去维护外键关系了。但是有一个问题,对象上就没有关联了,我们要做的是对象上要互相关联,数据库方面只让一方去维护关系即可。
对象上如果不关联,因为部门和员工添加到数据库后,是持久化状态,存在于session缓存中,那session操作缓存中这几个对象时,部门就没有关联员工了,那么就还得再查询一次数据库,这不是想要的结果。
这时就要用到mappedBy属性了。
在一的一方配置@OneToMany(mappedBy="department"),将维护权交由多的一方来维护;
那为什么不让多的一方交出维护权,让一的一方来维护呢?上面的实验也表明了如果让一的一方来维护,始终都会多出两条update语句,因为外键是在多的这一方的,所以维护权应该交由多的一方。
部门类的配置:第36行和第37行的配置,部门部门交出维护权利,让对方来维护
package com.lizhou.entity.test; import java.util.ArrayList;
import java.util.List; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; /**
* 部门:与员工一对多关系
* @author bojiangzhou
*
*/
@Entity
@Table(name="department")
public class Department { @Id
@GeneratedValue(generator="_native")
@GenericGenerator(name="_native", strategy="native")
private int id; //ID @Column(length=20)
private String dname; //部门名称 @OneToMany(mappedBy="department")
private List<Employee> employeeList = new ArrayList<>(); //部门下的员工集合 // get/set方法
}
员工类的配置不变。
调用testSave时,部门和员工再对象上依然是关联的:第46-49行
package com.lizhou.action.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lizhou.entity.test.Department;
import com.lizhou.entity.test.Employee; /**
* 测试类
* @author bojiangzhou
*
*/ public class TestAction { private static SessionFactory sessionFactory = null; static {
//读取classpath中applicationContext.xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取session中配置的sessionFactory对象
sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
} @Test
public void testSave(){
//创建一个部门对象
Department d1 = new Department();
d1.setDname("研发部"); //创建两个员工对象
Employee e1 = new Employee();
e1.setEname("张三");
e1.setPhone("13111111111");
Employee e2 = new Employee();
e2.setEname("李四");
e2.setPhone("18523222222"); //设置对象关联
d1.getEmployeeList().add(e1);
d1.getEmployeeList().add(e2);
e1.setDepartment(d1);
e2.setDepartment(d1); //获取Session
Session session = sessionFactory.openSession();
//开始事务
Transaction t = session.beginTransaction();
try {
//添加数据
session.save(d1);
session.save(e1);
session.save(e2);
//提交事务
t.commit();
} catch (RuntimeException e) {
//有异常则回滚事务
t.rollback();
e.printStackTrace();
} finally {
//关闭session
session.close();
}
} }
控制台打印的语句:只有三条插入语句,没有更新语句了
Hibernate: insert into department (dname) values (?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
这里遇到一个问题:如果配置mappedBy属性的同时加上@JoinColumn会抛出异常,所以不能同时使用@JoinColumn和mappedBy;因为@JoinColumn本身就是自己来维护外键,和mappedBy冲突了。--->>>不知道这样理解正确否!!^_^
package com.lizhou.entity.test; import java.util.ArrayList;
import java.util.List; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; /**
* 部门:与员工一对多关系
* @author bojiangzhou
*
*/
@Entity
@Table(name="department")
public class Department { @Id
@GeneratedValue(generator="_native")
@GenericGenerator(name="_native", strategy="native")
private int id; //ID @Column(length=20)
private String dname; //部门名称 @OneToMany(mappedBy="department")
@JoinColumn(name="departmentId")
private List<Employee> employeeList = new ArrayList<>(); //部门下的员工集合 // set/get 方法
}
抛出如下异常:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.lizhou.entity.test.Department.employeeList
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:684)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.lizhou.action.test.TestAction.<clinit>(TestAction.java:26)
... 22 more
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.lizhou.entity.test.Department.employeeList
at org.hibernate.cfg.annotations.CollectionBinder.bind(CollectionBinder.java:493)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2156)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:343)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:431)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 34 more
还有一点说明下:
如果将第57行代码移到第59行后面,即先保存员工,再保存部门,会多出四条update语句
package com.lizhou.action.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lizhou.entity.test.Department;
import com.lizhou.entity.test.Employee; /**
* 测试类
* @author bojiangzhou
*
*/ public class TestAction { private static SessionFactory sessionFactory = null; static {
//读取classpath中applicationContext.xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取session中配置的sessionFactory对象
sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
} @Test
public void testSave(){
//创建一个部门对象
Department d1 = new Department();
d1.setDname("研发部"); //创建两个员工对象
Employee e1 = new Employee();
e1.setEname("张三");
e1.setPhone("13111111111");
Employee e2 = new Employee();
e2.setEname("李四");
e2.setPhone("18523222222"); //设置对象关联
d1.getEmployeeList().add(e1);
d1.getEmployeeList().add(e2);
e1.setDepartment(d1);
e2.setDepartment(d1); //获取Session
Session session = sessionFactory.openSession();
//开始事务
Transaction t = session.beginTransaction();
try {
//添加数据
session.save(e1);
session.save(e2);
session.save(d1);
//提交事务
t.commit();
} catch (RuntimeException e) {
//有异常则回滚事务
t.rollback();
e.printStackTrace();
} finally {
//关闭session
session.close();
}
} }
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: insert into employee (departmentId, ename, phone) values (?, ?, ?)
Hibernate: insert into department (dname) values (?)
Hibernate: update employee set departmentId=?, ename=?, phone=? where id=?
Hibernate: update employee set departmentId=?, ename=?, phone=? where id=?
Hibernate: update employee set departmentId=? where id=?
Hibernate: update employee set departmentId=? where id=?
很明显,在插入员工时,还没有部门的信息,等插入部门的时候,员工方会维护外键关系,更新外键;而部门方也会维护一次,所以多了四条语句。所以在添加数据的时候先保存一的一方,再保存多的一方。
总结:mappedBy属性跟xml配置文件里的inverse一样。在一对多或一对一的关系映射中,如果不表明mappedBy属性,默认是由本方维护外键。但如果两方都由本方来维护的话,会多出一些update语句,性能有一定的损耗。
解决的办法就是在一的一方配置上mappedBy属性,将维护权交给多的一方来维护,就不会有update语句了。
至于为何要将维护权交给多的一方,可以这样考虑:要想一个国家的领导人记住所有人民的名字是不可能的,但可以让所有人民记住领导人的名字!
注意,配了mappedBy属性后,不要再有@JoinColumn,会冲突!
OK!!!
hibernate基于注解的维护权反转:@OneToMany(mappedBy=)的更多相关文章
- Hibernate基于注解方式的各种映射全面总结
1. 使用Hibernate Annotation来做对象关系映射 1) 添加必须包: hibernate-jpa-2.0-api-1.0.0.Final.jar 2) 在实体类中添加JPA的标准注解 ...
- Hibernate基于注解的双向one-to-many映射关系的实现
在项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现.可是公司的大部分都是基于注解的.因此自己參考之前的代码捣鼓了基于注解的一对多的映射关系实现. 背景: 一的一端:QingAo ...
- Hibernate基于注解annotation的配置
Annotation在框架中是越来越受欢迎了,因为annotation的配置比起XML的配置来说方便了很多,不需要大量的XML来书写,方便简单了很多,只要几个annotation的配置,就可以完成我们 ...
- hibernate基于注解实现映射关系的配置
关联关系的配置步骤 ①要理清楚管理关系 ②确定管理依赖关系的哪一方 1一对一例如:person 和IdCard ①确定依赖关系:一对一 ②依赖关系由person类管理代码如下: person: @En ...
- Hibernate基于注解实现自关联树形结构实现
很久没用过Hibernate了,项目需求需要使用,并建立树形结构,在开发中遇到一些问题,在这里记录一下. 1.创建数据库表,主要是设置标志信息,不然插入数据库会报id不能插入null的错误. 2.创建 ...
- Hibernate基于注解方式配置来实现实体和数据库之间存在某种映射关系
实体和数据库之间存在某种映射关系,hibernate根据这种映射关系完成数据的存取.在程序中这种映射关系由映射文件(*.hbm.xml)或者java注解(@)定义. 本文以java注解的形式总结映射关 ...
- springdata 一对多 级联操作 在注解里面开启级联操作@OneToMany(mappedBy = "customer",cascade = CascadeType.ALL)
- Hibernate基于【XML】和【注解】——完整实例
Eclipse中新建Java Project工程: 工程结构 和 需要的Jar包: 我用的SqlServer数据库,所以连接数据库的Jar包是sqljdbc4.jar 一.基于XML配置 1.实体 ...
- hibernate annotation注解方式来处理映射关系
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...
随机推荐
- Quartz.NET
http://www.360doc.com/userhome.aspx?userid=11741424&cid=2#
- Spring+Mybatis+SpringMVC+Maven+MySql搭建实例
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何使用Maven来搭建Spring+Mybatis+SpringMVC+M ...
- stl 比较和boost LessThanComparable
C++ STL的几种常用“比较”概念简述 在C++的现行标准(C++ 98)中,由于没有类似“接口”这样的东西,我们在泛型编程时往往只能对模板类型作一些假设,要求其符合某个需求清单,也就是属于某个 ...
- IIS7 应用程序池设置成 经典 v2.0
HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipe ...
- ASP.NET MVC URL重写与优化(1)-使用Global路由表定制URL
ASP.NET MVC URL重写与优化(1)-使用Global路由表定制URL 引言--- 在现今搜索引擎制霸天下的时代,我们不得不做一些东西来讨好爬虫,进而提示网站的排名来博得一个看得过去的流量. ...
- C#实现执行多条SQl语句,实现数据库事务
C#实现执行多条SQl语句,实现数据库事务 在数据库中使用事务的好处,相信大家都有听过银行存款的交易作为事务的一个例子.事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的 ...
- 161222、Bootstrap table 服务器端分页示例
bootstrap版本 为 3.X bootstrap-table.min.css bootstrap-table-zh-CN.min.js bootstrap-table.min.js 前端boot ...
- Python之ftplib模块
一.引言: 某一天,开发哥们跟我反映lftp和java写的ftp程序下载文件有问题,具体情况如下:当一个大于1G的文件已经下载完毕以后一直出现夯住的情况.为了重现开发哥们所说情况,我就自己用pytho ...
- SVN merge的主干,分支的相互合并操作
本文只研究了 在本地如何进行主干,分支的相互合并 的操作:从主干到分支,从分支到主干. 本地客户端工具是tortoisesvn 测试用例. 1.本地添加test文件夹 在test文件夹下分别建立tru ...
- Vue-简单购物车
优点 体积小.接口灵活.侵入性好,可用于页面的一部分,而不是整个页面.扩展性好.源码规范简洁.代码较为活跃,作者是中国人,可在官方论坛中文提问.github9000+.基于组件化的开发. 缺点 社区不 ...