2011.09.14

 

 

 

在多线程并发访问数据库并且使用事务的时候, 可能会遇到脏读, 不可重复读, 幻读的情况, 需要设置隔离级别来避免

 

脏读: 读到的线程未提交的数据

不可重复读: 在一个事务中读取同一个记录两次, 获取数据不同

幻读: 在一个事务中, 读取到的记录数不同

 

隔离级别

脏读

不可重复读

幻读

读未提交 Read Uncommitted

   √

读已提交 Read Committed

 

   √

   √

可重复读 Repeatable Read

 

 

   √

可序列化 Serializable

  

  

  

 

select @@tx_isolation;

查看隔离级别

set transaction isolation level read uncommitted;

设置读未提交

set transaction isolation level read committed;

设置读已提交

set transaction isolation level repeatable read;

设置可重复读

set transaction isolation level serializable;

设置可序列化

start transaction;

开始事务

rollback;

回滚事务

commit;

提交事务

1.      获取插入的ID

conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

ResultSet rs = ps.getGeneratedKeys();

if (rs.next())

    user.setId(rs.getInt(1));

 

MySQL的select last_insert_id()可以获取之前插入的记录的id, 但这只是MySQL才有的函数

 

只有对自增长的列发生自增长的赋值后才会导致一个key的产生,并且用getGereratedKeys()返回。

2.      批处理

由于建立连接, 以及发送数据非常消耗性能, 如果有大批SQL命令需要处理, 最好使用批处理

 

ps = conn.prepareStatement("insert into user(name,password,email,birthday) values(?,?,?,?)");

for (User user : list) {

    ps.setString(1, user.getName());

    ps.setString(2, user.getPassword());

    ps.setString(3, user.getEmail());

    ps.setDate(4, new Date(user.getBirthday().getTime()));

    ps.addBatch();

}

ps.executeBatch();

3.      分页

通过ResultSet的滚动可以设置获取记录的位置, 但这样是从数据库中查询出所有数据, 然后再从结果中筛选结果, 性能非常低.

 

MySQL提供了分页语法. 在查询语句后可使用LIMIT关键字完成分页功能, 例如:

 

select * from user limit 40,20

 

查询从user表中取出从第41条开始的20条记录. 第一个参数表示忽略前面多少个, 第二个参数代表取多少个.

4.      可更新结果集、敏感结果集

conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

 

ResultSet.TYPE_SCROLL_SENSITIVE

表示获得ResultSet之后是敏感的, 随数据库更新的. 但MySQL没有支持这项功能

 

ResultSet.CONCUR_UPDATABLE

表示获得ResultSet之后是可更新的, 例如:

rs.next();

rs.updateString("name", "updateName");

rs.updateRow();

可以将当前行的name属性改为updateName.

5.      元信息

5.1.      数据库元信息

由于每种数据库对JDBC的实现都有所不同, 我们在使用的时候想要了解哪些数据库支持哪些功能, 就可以查看元信息

 

数据库版本号

data.getDriverName()DatabaseMetaData data = conn.getMetaData();

数据库元信息

data.getDatabaseProductName()

数据库名

data.getDatabaseProductVersion()

 

驱动名

data.getDriverVersion()

驱动版本号

data.supportsTransactions()

是否支持事务

data.getDefaultTransactionIsolation()

默认事务隔离级别

data.supportsTransactionIsolationLevel(0)

是否支持指定的事务隔离级别

data.supportsGetGeneratedKeys()

是否支持获取主键

data.supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE)

是否支持敏感结果集

5.2.      结果集元信息

我们可以根据结果集元信息来写一些灵活性很高的代码. 让代码的复用性更高.

 

ResultSetMetaData rsmd = ps.getMetaData();

获取结果集元信息

rsmd.getColumnCount()

获取结果集中包含几列

rsmd.getColumnName(1)

获取指定列的名字

rsmd.getColumnLabel(1)

获取指定列的别名

rsmd.getColumnClassName(1)

获取指定列的Java类型

rsmd.getColumnTypeName(1)

获取指定列的数据库类型

6.      反射基础

6.1.      构造函数

Class.getConstructors()

获取所有构造函数

Class.getConstructor(Class...);

获取到class中带有指定类型参数的构造函数

Constructor.newInstance(Object...);

使用构造函数创建对象, 传入指定参数

6.2.      方法

Class.getMethods()

获取所有公有方法, 包括继承的

Class.getDeclaredMethods()

获取所有类中定义的方法, 包括私有的

Class.getMethod(String, Class...)

获取指定方法名和参数类型的方法(公有的)

Class.getDeclaredMethod(String, Class...)

获取指定方法名和参数类型的方法(类中定义的)

Method.invoke(Object, Object...)

在制定对象上运行方法, 将制定参数传入

6.3.      属性

Class.getFields()

获取所有公有属性(包括父类继承的)

Class.getDeclaredFields()

获取所有定义的属性(包括私有的)

Class.getField(String)

获取指定属性(公有属性)

Class.getDeclaredField(String)

获取指定属性(定义属性)

Field.set(Object, Object)

设置指定对象的属性值

Field.get(Object)

获取指定对象的属性值

Filed.setAccessible(Boolean)

设置访问权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来为您解答这个问题。 首先,我们需要将数据整理成R可处理的格式。这里,我将数据手动输入到R中,并将其保存为data.frame对象: ```R transportation <- data.frame( year = 2002:2021, railway = c(366.34, 375.14, 401.82, 419.16, 436.38, 447.02, 471.85, 487.8, 503.12, 518.25, 516.16, 522.77, 516.81, 532.08, 531.9, 527, 524.47, 511.09, 492, 476), highway = c(71.31, 67.32, 68.07, 67.88, 67.03, 66.3, 66.35, 63.34, 60.7, 51.92, 51, 49.2, 48.62, 46.52, 56.11, 54.45, 54.74, 54, 53, 45), water = c(20.27, 22.01, 29.42, 28.44, 27.44, 26.56, 27, 28.27, 29.03, 30.09, 30.35, 32.27, 31.09, 29.1, 34.06, 33.38, 33.5, 34.8, 37, 39), air = c(1482.14, 1510.68, 1773.71, 1751.13, 1724.75, 1716.97, 1669.62, 1616.08, 1598.11, 1573.69, 1547.57, 1508.83, 1464.21, 1497.47, 1502.85, 1484.65, 1479, 1470, 1442, 1432) ) ``` 接下来,我们可以使用ggplot2库绘制各种图形来更好地理解数据。 首先,我们可以使用ggplot2库绘制各种运输方式的时间序列折线图,代码如下: ```R library(ggplot2) ggplot(melt(transportation, id.vars = "year"), aes(x = year, y = value, color = variable)) + geom_line() + xlab("Year") + ylab("Passenger Distance") + ggtitle("Passenger Distance by Transportation Type") + theme(legend.position = "bottom") ``` 运行上面的代码,可以得到一个绘制了四种运输方式的时间序列折线图。 接着,我们可以使用ggplot2库绘制各种运输方式的密度图,代码如下: ```R ggplot(melt(transportation, id.vars = "year"), aes(x = value, fill = variable)) + geom_density(alpha = 0.5) + xlab("Passenger Distance") + ylab("Density") + ggtitle("Passenger Distance Density by Transportation Type") ``` 运行上面的代码,可以得到一个绘制了四种运输方式的密度图。 最后,我们可以使用ggplot2库绘制各种运输方式的箱线图,代码如下: ```R ggplot(melt(transportation, id.vars = "year"), aes(x = variable, y = value, fill = variable)) + geom_boxplot() + xlab("Transportation Type") + ylab("Passenger Distance") + ggtitle("Passenger Distance by Transportation Type") ``` 运行上面的代码,可以得到一个绘制了四种运输方式的箱线图。 以上是本次数据分析的R代码和图形,希望能够帮到您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值