发表于: 2018-06-10 22:49:30
1 866
今天完成的事情:
1.jdbctemplate批量插入
2.嵌套for循环
3.StringBuffer学习
4.了解Spring事务管理
1.jdbctemplate批量插入
批量插入代码如下:
packagecpm.Mybatis;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.SQLException;
importjava.util.Date;
public classTest2 {
public static voidmain(String[]args)throwsException{
//连接数据库
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","0214");
Long begin =newDate().getTime();
// sql前缀
String prefix ="INSERT INTO teacher (name,cd) VALUES ";
try{
StringBuffer suffix =newStringBuffer();
// 设置事务为非自动提交
conn.setAutoCommit(false);
PreparedStatement pst = conn.prepareStatement("");
// 外层循环,总提交事务次数
for(inti =1;i <=100;i++) {
for(intj =1;j <=1000;j++) {
// 构建sql后缀
suffix.append("('张三','110'),");
}
// 构建完整sql
String sql = prefix + suffix.substring(0,suffix.length() -1);
// 添加执行sql
pst.addBatch(sql);
// 执行操作
pst.executeBatch();
// pst.executeLargeBatch();
// 提交事务
conn.commit();
// 清空上一次添加的数据
suffix =newStringBuffer();
}
pst.close();
conn.close();
}catch(SQLException e) {
e.printStackTrace();
}
// 结束时间
Long end =newDate().getTime();
// 耗时
System.out.println("cast : "+ (end - begin) /1000+" s");
}
}
执行结果如下:
在navicate查询表如下:
2.嵌套for循环
嵌套for循环两种形式:
第一种:
public classFor1 {
public static voidmain(String[] args) {
inti,j;
for(i =0;i <=7;i++) {// 外层循环控制行数
for(j =0;j <=7;j++) {// 内层循环打印 *
System.out.print("*"); // 注意不是 println
}
System.out.print("\n");//换行
}
}
}
执行结果如下:
第两种:
public classFor2 {
public static voidmain(String[] args) {
inti,j;
for(i =0;i <5;i++) {
for(j =0;j <= i;j++){
System.out.print('#');
}
System.out.print("\n");//换行
}
}
}
执行结果如下:
第一种方式中,内部循环进行7次,外部循环也进行7次,相当于外部循环把内部循环的结果打印了7次,为什么呢?因为内部循环的条件是固定的(j<7),每次外部循环,内部循环都要进行7次,效果大家可想而知。第二种方式中,当外部循环进行第一次时,即i=0时,由于内部循环的条件为j<=i,此时0<=0,满足循环条件,在这种方式中,内部循环的条件每次都是变化的。因此,当外部循环进行一次时,内部循环进行打印出第一个打#,以此类推打印出了所有的#。
3.StringBuffer学习
1.what StringBuffer?
String和StringBuffer他们都可以存储和操作字符串,即包含多个字符的字符串数据。
String类是字符串常量,是不可更改的常量。而StringBuffer是字符串变量,它的对象是可以扩充和修改的。
StringBuffer类的构造函数
public StringBuffer()
创建一个空的StringBuffer类的对象。
public StringBuffer( int length )
创建一个长度为 参数length 的StringBuffer类的对象。
public StringBuffer( String str )
用一个已存在的字符串常量来创建StringBuffer类的对象。
StringBuffer对象的初始化不像String类的初始化一样,Java提供的有特殊的语法,而通常情况下一般使用构造方法进行初始化。
例如:
创建带有内容的StringBuffer对象,则可以使用:
StringBuffer s = new StringBuffer(“abc”);
这样初始化出的StringBuffer对象的内容就是字符串”abc”。
需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:
StringBuffer s = “abc”; //赋值类型不匹配
StringBuffer s = (StringBuffer)”abc”; //不存在继承关系,无法进行强转
StringBuffer对象和String对象之间的互转的代码如下:
String s = “abc”;
StringBuffer sb1 = new StringBuffer(“123”);
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer
String s1 = sb1.toString(); //StringBuffer转换为String
2、StringBuffer的常用方法
a、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”。
b、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“Test”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
c、insert方法
public StringBuffer insert(int offset, boolean b)
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
d、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
e、setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
f、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
4.了解Spring事务管理
初步理解
理解事务之前,先讲一个你日常生活中最常干的事:取钱。
比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。
事务就是用来解决类似问题的。事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。
在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。
事务有四个特性:ACID
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
Spring事务管理
Spring事务管理的核心接口是PlatformTransactionManager
事务管理器接口通过getTransaction(TransactionDefinition definition)方法根据指定的传播行为返回当前活动的事务或创建一个新的事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。
在TransactionDefinition接口中定义了它自己的传播行为和隔离级别
除去常量,主要的方法有:
int getIsolationLevel();// 返回事务的隔离级别
String getName();// 返回事务的名称
int getPropagationBehavior();// 返回事务的传播行为
int getTimeout(); // 返回事务必须在多少秒内完成
boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的
明天计划的事情:
明天计划实现jdbctemplate批量的更改和删除操作,开始Mybatis连接数据库的任务。
遇到的问题:
jdbctemplate批量插入的时候出现如下的错误:
起因是:java web程序中数据包太大设置mysql 中max_allowed_packet变量值
max_allowed_packet 默认值为1024,也就是1M,有的时候,我们在操作数据库的时,因为数据包过大查过了max_allowed_packet的最大值而导致程序异常。通常情况下我们是通过修改mysql的配置文件来修改其大小
解决方案:
1.打开navicat 连接数据库,新建查询命令,输入命令 show VARIABLES like '%max_allowed_packet%'; 发现max_allowed_packet为1024
2、打开mysql的安装目录,打开my.ini 找到 max_allowed_packet 将其值修改大点,比如20M。如果没有max_allowed_packet,则在该文件的末尾
添加
[mysqld]
max_allowed_packet = 20M
关闭保存my.ini文件,重启mysql。
如果还是出错,那就再设置大一点。
收获:
1.实现了jdbctemplate批量插入的功能,和昨天的批量插入效率得到大幅度的提高,通过嵌套for循环可以一次性的插入大量的数据。
2.学习了嵌套for循环,理解了两种不同的形式,其运行机制不同,可使用于不同的场景。
3.了解了StringBuffer,知道了其与String的区别,和一些用法。
4.大概了解了事务管理,如果用了事务管理就不用再去cath错误。
5.出现的问题也是一种收获。
评论