JAVA開發(fā)相關(guān)代碼模板(持續(xù)更新)

本文主要整理JAVA開發(fā)中的一些模板代碼,作為平時(shí)參考使用浙芙。

1 MongoTemplate

版本:mongoDb4.0

1.1 寫入數(shù)據(jù)

JSONObject json = new JSONObject();
json.put("userName", "張三");
json.put("age", 20);
json.put("sex", "男");
json.put("oneFlag", true);
json.put("towFlag", true);
json.put("indexNum", i + 1);
json.put("delFlag", "0");
mongoTemplate.insert(json, "t_user_info");

1.2 更新數(shù)據(jù)

// ----------[組裝查詢條件]----------
Query query = new Query();
query.addCriteria(Criteria.where("indexNum").is(1));

// ----------[組裝更新邏輯]----------
Update update = new Update();
update.set("userName", "李四");
update.set("age", 19);

// ----------[更新數(shù)據(jù)]----------
UpdateResult updateResult = mongoTemplate.updateMulti(query, update, "t_user_info");
System.out.println("匹配數(shù)量:"+updateResult.getMatchedCount());
// 如果更新后數(shù)據(jù)和更新前一樣损敷,則getModifiedCount()返回0
System.out.println("更新數(shù)量:"+updateResult.getModifiedCount());

1.3 基本查詢

Query query = new Query();
// ----------[拼接查詢條件]----------
// 等于
query.addCriteria(Criteria.where("delFlag").is("0"));
// 字符串模糊查詢
query.addCriteria(Criteria.where("userName").regex("^.*張三.*$"));
// 數(shù)值比較(大于)
query.addCriteria(Criteria.where("age").gte(20));
// 集合查詢
query.addCriteria(Criteria.where("sex").in(Arrays.asList("男", "女")));
// 或條件
query.addCriteria(new Criteria().orOperator(Criteria.where("oneFlag").is(true), Criteria.where("towFlag").is(true)));

// ----------[排序]----------
query.with(Sort.by(new Sort.Order(Sort.Direction.DESC, "age"), new Sort.Order(Sort.Direction.ASC, "indexNum")));

// ----------[指定查詢字段]----------
query.fields().include("userName").include("age").include("sex").include("indexNum");

// ----------[分頁]----------
// 當(dāng)前頁數(shù)
int pageNumber = 1;
// 每頁數(shù)量
int pageLimit = 10;
query.skip((pageNumber - 1) * pageLimit).limit(pageLimit);

// ----------[執(zhí)行查詢]----------
List<Document> list = mongoTemplate.find(query, Document.class, "t_user_info");
// 輸出內(nèi)容:【Query: { "delFlag" : "0", "userName" : { "$regex" : "^.*張三.*$", "$options" : ""}, "age" : { "$gte" : 20}, "sex" : { "$in" : ["男", "女"]}, "$or" : [{ "oneFlag" : true}, { "towFlag" : true}]}, Fields: { "indexNum" : 1, "sex" : 1, "userName" : 1, "age" : 1}, Sort: { "age" : -1, "indexNum" : 1}】
System.out.println(query.toString());

1.4 組裝查詢條件

(1)錯(cuò)誤場(chǎng)景

mongoTemplate的query在組裝查詢條件時(shí)男应,執(zhí)行query.addCriteria搞疗,不能對(duì)統(tǒng)一字段執(zhí)行多次此操作,否則會(huì)拋出InvalidMongoDbApiUsageException異常剥懒。

錯(cuò)誤代碼,如下:

Query query = new Query();
// 對(duì)字段age合敦,添加多個(gè)條件
query.addCriteria(Criteria.where("age").gte(20));
query.addCriteria(Criteria.where("age").lte(30));
List<Document> list = mongoTemplate.find(query, Document.class, "t_user_info");

此種情況初橘,拋出異常信息如下:

org.springframework.data.mongodb.InvalidMongoDbApiUsageException: Due to limitations of the com.mongodb.BasicDocument, you can't add a second 'age' criteria. Query already contains '{ "age" : { "$gte" : 20}}'

(2)解決方案-1

同一個(gè)字段,拼接多個(gè)條件充岛。

Query query = new Query();
query.addCriteria(Criteria.where("age").gte(20).lte(30));
List<Document> list = mongoTemplate.find(query, Document.class, "t_user_info");
// 輸出內(nèi)容:【Query: { "age" : { "$gte" : 20, "$lte" : 30}}, Fields: {}, Sort: {}】
System.out.println(query);

(3)解決方案-2(建議)

將查詢條件保檐,拼接為and模式

List<Criteria> criteriaList = new ArrayList<>();
criteriaList.add(Criteria.where("age").gte(20));
criteriaList.add(Criteria.where("age").lte(30));

Criteria[] criteriaArr= new Criteria[criteriaList.size()];
criteriaList.toArray(criteriaArr);

Criteria criteria = new Criteria();
criteria.andOperator(criteriaArr);

Query query = new Query();
query.addCriteria(criteria);

List<Document> list = mongoTemplate.find(query, Document.class, "t_user_info");
// 輸出內(nèi)容:【Query: { "$and" : [{ "age" : { "$gte" : 20}}, { "age" : { "$lte" : 30}}]}, Fields: {}, Sort: {}】
System.out.println(query);

1.5 游標(biāo)查詢

試用于海量數(shù)據(jù)查詢

// ----------[組裝查詢條件]----------
Query query = new Query();
query.addCriteria(Criteria.where("sex").is("男"));

// ----------[游標(biāo)查詢]----------
try(MongoCursor<Document> cursor = mongoTemplate.getCollection("t_user_info").find(query.getQueryObject()).batchSize(1000).noCursorTimeout(true).cursor();) {
    while (cursor.hasNext()){
        Document document = cursor.next();
        // TODO 執(zhí)行業(yè)務(wù)方法
    }
}catch (Exception e){
    e.printStackTrace();
}

1.6 聚合查詢

// ----------[分頁相關(guān)]----------
// 頁數(shù)
long pageNumber = 1;
// 每頁數(shù)量
long pageLimit = 10;

// ----------[查詢條件相關(guān)]----------
// where
Criteria whereCriteria = new Criteria().andOperator(Criteria.where("delFlag").is("0"));
// having
Criteria havingCriteria = new Criteria().andOperator(Criteria.where("count").gte(500));

// ----------[分組查詢]----------
Aggregation aggregation = Aggregation.newAggregation(
    // 條件(match在group前作為where使用)
    Aggregation.match(whereCriteria),
    // 分組條件(group by sex, userName)
    Aggregation.group("sex", "userName").max("indexNum").as("maxIndexNum").count().as("count"),
    //having(match在group后作為having使用)
    Aggregation.match(havingCriteria),
    // 映射字段到前臺(tái)
    Aggregation.project("sex", "userName", "maxIndexNum", "count"),
    // 排序
    Aggregation.sort(Sort.by(new Sort.Order(Sort.Direction.ASC, "sex"))),
    // 分頁
    Aggregation.skip((pageNumber - 1) * pageLimit),
    Aggregation.limit(pageLimit)
);
// Mongodb規(guī)定了aggregate管道聚合的返回?cái)?shù)據(jù)不能超過`16M`,超過16M就會(huì)報(bào)異常錯(cuò)誤崔梗。解決方法就是設(shè)置`allowDiskUse:true`夜只,即允`許使用磁盤緩存`
aggregation = aggregation.withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());

// 輸出內(nèi)容:【{ "aggregate" : "__collection__", "pipeline" : [{ "$match" : { "$and" : [{ "delFlag" : "0"}]}}, { "$group" : { "_id" : { "sex" : "$sex", "userName" : "$userName"}, "maxIndexNum" : { "$max" : "$indexNum"}, "count" : { "$sum" : 1}}}, { "$match" : { "$and" : [{ "count" : { "$gte" : 500}}]}}, { "$project" : { "sex" : "$_id.sex", "userName" : "$_id.userName", "maxIndexNum" : 1, "count" : 1}}, { "$sort" : { "sex" : 1}}, { "$skip" : { "$numberLong" : "0"}}, { "$limit" : { "$numberLong" : "10"}}], "allowDiskUse" : true}】
System.out.println(aggregation.toString());
List<Map> list = mongoTemplate.aggregate(aggregation, "t_user_info", Map.class).getMappedResults();

1.7 MapReduce

1.7.1 注意事項(xiàng)

Map注意事項(xiàng):

  • 在map函數(shù)中,如果要引用當(dāng)前文檔自身蒜魄,可以使用this
  • 在一個(gè)map函數(shù)中可以任意多次調(diào)用emit函數(shù)來輸出具有key/value形式的中間數(shù)據(jù)

Reduce注意事項(xiàng):

  • 如果一個(gè)key只有一個(gè)value扔亥,那么MongoDB不調(diào)用reduce函數(shù)
  • 對(duì)于同一個(gè)key,reduce函數(shù)可能會(huì)執(zhí)行多次
1.7.2 mongo腳本

(1)輸出結(jié)果到實(shí)際的表

輸出結(jié)果到表中(以替換整張表的方式)

// 自定義map函數(shù)
var myMap = function() {
    emit(this.sex, this.age);
}
// 自定義reduce函數(shù)
var myReduce = function(key, values) {
    var totalAge = 0;
    for (var i = 0; i < values.length; i++) {
        totalAge = totalAge + values[i];
    }
    return totalAge;
}
// 執(zhí)行mapReduce方法
db.t_user_info.mapReduce(
    // 自定義map函數(shù)
    myMap,
    // 自定義reduce函數(shù)
    myReduce,
    {
        // 查詢條件
        query: {"delFlag" : "0"},
        // 輸出方式(整個(gè)替換輸出到表)(輸出到內(nèi)容中谈为,可用:"out: { inline: 1 }")
        out: "map_reduce_result"
    }
)

執(zhí)行后旅挤,輸出內(nèi)容如下:

/* 1 */
{
    // 存儲(chǔ)數(shù)據(jù)的集合
    "result" : "map_reduce_result",
    // 執(zhí)行花費(fèi)的時(shí)間(毫秒)
    "timeMillis" : 138.0,
    "counts" : {
        // 滿足條件被發(fā)送到map函數(shù)的文檔個(gè)數(shù)
        "input" : 1500,
        // 在map函數(shù)中emit被調(diào)用的次數(shù),也就是所有集合中的數(shù)據(jù)總量
        "emit" : 1500,
        // 滿足條件被發(fā)送到reduce函數(shù)的文檔個(gè)數(shù)
        "reduce" : 15,
        // 結(jié)果集合中的文檔個(gè)數(shù)
        "output" : 2
    },
    // 是否成功伞鲫,成功為1
    "ok" : 1.0,
    "_o" : {
        "result" : "map_reduce_result",
        "timeMillis" : 138,
        "counts" : {
            "input" : 1500,
            "emit" : 1500,
            "reduce" : 15,
            "output" : 2
        },
        "ok" : 1.0
    },
    "_keys" : [ 
        "result", 
        "timeMillis", 
        "counts", 
        "ok"
    ],
    "_db" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.0.11:40001",
            "defaultDB" : "aaDb",
            "authStatus" : {
                "authRequired" : true,
                "isMaster" : true,
                "replSetGetStatus" : true
            },
            "_readMode" : "commands"
        },
        "_name" : "aaDb"
    },
    "_coll" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.0.11:40001",
            "defaultDB" : "aaDb",
            "authStatus" : {
                "authRequired" : true,
                "isMaster" : true,
                "replSetGetStatus" : true
            },
            "_readMode" : "commands"
        },
        "_db" : {
            "_mongo" : {
                "slaveOk" : true,
                "host" : "192.168.0.11:40001",
                "defaultDB" : "aaDb",
                "authStatus" : {
                    "authRequired" : true,
                    "isMaster" : true,
                    "replSetGetStatus" : true
                },
                "_readMode" : "commands"
            },
            "_name" : "aaDb"
        },
        "_shortName" : "map_reduce_result",
        "_fullName" : "aaDb.map_reduce_result"
    }
}

執(zhí)行結(jié)束后粘茄,表map_reduce_result中結(jié)果如下:

/* 1 */
{
    "_id" : "女",
    "value" : 12500.0
}

/* 2 */
{
    "_id" : "男",
    "value" : 19999.0
}

(2)輸出到內(nèi)存

如只想獲取,計(jì)算結(jié)果秕脓,不想將數(shù)據(jù)結(jié)果輸出到實(shí)際的表中柒瓣。可以將out進(jìn)行如下配置吠架,將結(jié)果芙贫,輸出到內(nèi)存中

out: { inline: 1 }

這個(gè)選項(xiàng)只有在結(jié)果集單個(gè)文檔大小在16MB限制范圍內(nèi)時(shí)才有效

完整腳本如下:

// 自定義map函數(shù)
var myMap = function() {
    emit(this.sex, this.age);
}
// 自定義reduce函數(shù)
var myReduce = function(key, values) {
    var totalAge = 0;
    for (var i = 0; i < values.length; i++) {
        totalAge = totalAge + values[i];
    }
    return totalAge;
}
// 執(zhí)行mapReduce方法
db.t_user_info.mapReduce(
    // 自定義map函數(shù)
    myMap,
    // 自定義reduce函數(shù)
    myReduce,
    {
        // 查詢條件
        query: {"delFlag" : "0"},
        // 輸出方式(內(nèi)存臨時(shí)表)
        out: { inline: 1 }
    }
)

輸出結(jié)果如下(可見results屬性中,可以看到計(jì)算的最終結(jié)果)

/* 1 */
{
    "results" : [ 
        {
            "_id" : "女",
            "value" : 12500.0
        }, 
        {
            "_id" : "男",
            "value" : 19999.0
        }
    ],
    "timeMillis" : 81.0,
    "counts" : {
        "input" : 1500,
        "emit" : 1500,
        "reduce" : 15,
        "output" : 2
    },
    "ok" : 1.0,
    "_o" : {
        "results" : [ 
            {
                "_id" : "女",
                "value" : 12500.0
            }, 
            {
                "_id" : "男",
                "value" : 19999.0
            }
        ],
        "timeMillis" : 81,
        "counts" : {
            "input" : 1500,
            "emit" : 1500,
            "reduce" : 15,
            "output" : 2
        },
        "ok" : 1.0
    },
    "_keys" : [ 
        "results", 
        "timeMillis", 
        "counts", 
        "ok"
    ],
    "_db" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.0.11:40001",
            "defaultDB" : "aaDb",
            "authStatus" : {
                "authRequired" : true,
                "isMaster" : true,
                "replSetGetStatus" : true
            },
            "_readMode" : "commands"
        },
        "_name" : "aaDb"
    }
}
1.7.3 mongoTemplate

(1)寫入到內(nèi)存中

// (1)定義map函數(shù)
String mapFun = "function() {\n" +
    "    emit(this.sex, this.age);\n" +
    "}";
// (2)定義reduce函數(shù)
String reduceFun = "function(key, values) {\n" +
    "    var totalAge = 0;\n" +
    "    for (var i = 0; i < values.length; i++) {\n" +
    "        totalAge = totalAge + values[i];\n" +
    "    }\n" +
    "    return totalAge;\n" +
    "}";

// (3)執(zhí)行mapReduce方法
MapReduceResults<Document> mapReduceResults = mongoTemplate.mapReduce(new Query(Criteria.where("delFlag").is("0")), "t_user_info", mapFun, reduceFun, Document.class);

// (4)輸出執(zhí)行結(jié)果
Iterator<Document> iterator = mapReduceResults.iterator();
while (iterator.hasNext()) {
    // Document{{_id=女, value=12500.0}}
    // Document{{_id=男, value=19999.0}}
    System.out.println(iterator.next());
}

(2)寫入到表

// (1)定義map函數(shù)
String mapFun = "function() {\n" +
    "    emit(this.sex, this.age);\n" +
    "}";

// (2)定義reduce函數(shù)
String reduceFun = "function(key, values) {\n" +
    "    var totalAge = 0;\n" +
    "    for (var i = 0; i < values.length; i++) {\n" +
    "        totalAge = totalAge + values[i];\n" +
    "    }\n" +
    "    return totalAge;\n" +
    "}";

// (3)定義相關(guān)屬性配置
MapReduceOptions mapReduceOptions = MapReduceOptions.options().outputCollection("my_map_reduce_res");

// (4)執(zhí)行mapReduce方法
MapReduceResults<Document> mapReduceResults = mongoTemplate.mapReduce(new Query(Criteria.where("delFlag").is("0")), "t_user_info", mapFun, reduceFun, mapReduceOptions, Document.class);

// (5)輸出執(zhí)行結(jié)果
Iterator<Document> iterator = mapReduceResults.iterator();
while (iterator.hasNext()) {
    // Document{{_id=女, value=12500.0}}
    // Document{{_id=男, value=19999.0}}
    System.out.println(iterator.next());
}

根據(jù)輸出結(jié)果诵肛,可見屹培,仍然可在對(duì)象MapReduceResults中獲取執(zhí)行結(jié)果默穴,執(zhí)行結(jié)束后,查詢數(shù)據(jù)庫褪秀,可見目標(biāo)表my_map_reduce_res中蓄诽,已生成我們需要的數(shù)據(jù)。

/* 1 */
{
    "_id" : "女",
    "value" : 12500.0
}

/* 2 */
{
    "_id" : "男",
    "value" : 19999.0
}

1.8 bulk

主要適用于批量更新媒吗,減少更新請(qǐng)求的調(diào)用次數(shù)仑氛。也可混合使用(寫入、更新闸英、刪除)锯岖。

(1)寫法1

// ----------[定義更新集合]----------
List<Pair<Query, Update>> updatePairList = new ArrayList<>();

// ----------[組裝更新集合]----------
// 組裝更新數(shù)據(jù)1
Query query1 = new Query();
query1.addCriteria(Criteria.where("indexNum").is(1));
Update update1 = new Update();
update1.set("delFlag", "11");
Pair<Query, Update> updatePair1 = Pair.of(query1, update1);
updatePairList.add(updatePair1);

// 組裝更新數(shù)據(jù)2
Query query2 = new Query();
query2.addCriteria(Criteria.where("indexNum").is(2));
Update update2 = new Update();
update2.set("delFlag", "12");
Pair<Query, Update> updatePair2 = Pair.of(query2, update2);
updatePairList.add(updatePair2);

// ......

// ----------[更新數(shù)據(jù)]----------
BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "t_user_info");
operations.updateOne(updatePairList);
BulkWriteResult writeResult = operations.execute();
boolean result = writeResult.wasAcknowledged();
System.out.println("執(zhí)行結(jié)果:" + result);

(2)寫法2

 // ----------[定義操作對(duì)象]----------
BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "t_user_info");

// ----------[組裝更新集合]----------
// 組裝更新數(shù)據(jù)1
Query query1 = new Query();
query1.addCriteria(Criteria.where("indexNum").is(1));
Update update1 = new Update();
update1.set("delFlag", "21");
operations.updateOne(query1,update1);

// 組裝更新數(shù)據(jù)2
Query query2 = new Query();
query2.addCriteria(Criteria.where("indexNum").is(2));
Update update2 = new Update();
update2.set("delFlag", "22");
operations.updateOne(query2,update2);

// ......
// operations.insert()
// operations.remove()

// ----------[更新數(shù)據(jù)]----------
BulkWriteResult writeResult = operations.execute();
boolean result = writeResult.wasAcknowledged();
System.out.println("執(zhí)行結(jié)果:" + result);

1.9 切換到主庫查詢

默認(rèn)readPreference為ReadPreference.secondaryPreferred()時(shí),可通過如下方式甫何,臨時(shí)設(shè)置從主庫讀取數(shù)據(jù)出吹。

也可設(shè)置專門從主庫讀取數(shù)據(jù)的mongoTemplate句柄

// mongoTemplate切換到主庫查詢
try {
    mongoTemplate.setReadPreference(ReadPreference.primary());
    
    // TODO 執(zhí)行查詢操作......

}catch (Exception e){
    // 異常(處理或拋出)
    e.printStackTrace();
}finally {
    // 切換回默認(rèn)的ReadPreference
    mongoTemplate.setReadPreference(ReadPreference.secondary());
}

2 Mybatis

應(yīng)用數(shù)據(jù)庫:mysql辙喂。測(cè)試使用建表腳本如下:

CREATE TABLE `c_m_phone` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `phone_first` varchar(20) DEFAULT NULL COMMENT '前綴號(hào)段',
  `phone_provence` varchar(20) DEFAULT NULL COMMENT '手機(jī)所在省份',
  `phone_city` varchar(20) DEFAULT NULL COMMENT '手機(jī)所在城市',
  `service` varchar(20) DEFAULT NULL COMMENT '服務(wù)商',
  `area_number` int(10) DEFAULT NULL COMMENT '區(qū)號(hào)',
  `code` varchar(10) DEFAULT NULL COMMENT '郵編',
  PRIMARY KEY (`id`),
  UNIQUE KEY `phoneFirst` (`phone_first`) USING BTREE
) ENGINE=InnoDBDEFAULT CHARSET=utf8 COMMENT='電話區(qū)域表';

2.1 批量插入

適用于海量數(shù)據(jù)插入到數(shù)據(jù)庫的情況捶牢,用來提高寫入速度,建議上限5000巍耗。

Java方法:

int insertBatch(@Param("list") List<CMPhone> list);

xml:

<insert id="insertBatch">
    insert into c_m_phone(phone_first, phone_provence, phone_city, service, area_number, code)
    values
    <foreach collection="list" item="item" separator=",">
    (
        #{item.phoneFirst}, #{item.phoneProvence}, #{item.phoneCity},#{item.service}, #{item.areaNumber}, #{item.code}
    )
    </foreach>
</insert>

2.2 流式查詢

Java方法:

/**
 * 流式查詢數(shù)據(jù)
 * @param model   參數(shù)
 * @param handler 結(jié)果集
 * @return void
 */
void findByStream(@Param("model") CMPhone model, ResultHandler handler);

xml:

<resultMap id="BaseResultMap" type="com.tmp.demo.mysql.mapper.bean.CMPhone">
    <id column="id" property="id" jdbcType="INTEGER"/>
    <result column="phone_first" property="phoneFirst" jdbcType="VARCHAR"/>
    <result column="phone_provence" property="phoneProvence" jdbcType="VARCHAR"/>
    <result column="phone_city" property="phoneCity" jdbcType="VARCHAR"/>
    <result column="service" property="service" jdbcType="VARCHAR"/>
    <result column="area_number" property="areaNumber" jdbcType="INTEGER"/>
    <result column="code" property="code" jdbcType="VARCHAR"/>
</resultMap>

<select id="findByStream" resultMap="BaseResultMap" resultSetType="FORWARD_ONLY" fetchSize="-2147483648">
    select id, phone_first, phone_provence, phone_city, service, area_number, code
    from c_m_phone
    <where>
        <if test="model.phoneFirst != null and model.phoneFirst != '' ">
            AND phone_first like #{model.phoneFirst}
        </if>
    </where>
</select>

應(yīng)用:

CMPhone model = new CMPhone();
model.setPhoneFirst("%37%");
cmPhoneMapper.findByStream(model, (ResultHandler<CMPhone>) resultContext -> {
    System.out.println("第幾個(gè):" + resultContext.getResultCount());
    CMPhone cmPhone = resultContext.getResultObject();
    System.out.println("查詢結(jié)果:" + cmPhone);
});

2.3 自定義事務(wù)

@Autowired
private PlatformTransactionManager transactionManager;

@Autowired
private TransactionDefinition transactionDefinition;

/**
 * 自定義事務(wù)測(cè)試
 */
public void transactionTest() {
    // 開啟事務(wù)
    TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
    try {
        // ----------執(zhí)行數(shù)據(jù)庫操作----------start
        List<CMPhone> list = new ArrayList<>();
        CMPhone cmPhone = new CMPhone();
        cmPhone.setPhoneFirst("X1");
        list.add(cmPhone);
        cmPhoneMapper.insertBatch(list);
        // 如事務(wù)寫入的數(shù)據(jù)很多秋麸,且執(zhí)行時(shí)間太長,可中途進(jìn)行資源刷新(刷新緩存到數(shù)據(jù)庫炬太,提高速度)
        transactionStatus.flush();
        cmPhoneMapper.insertBatch(list);
        // ----------執(zhí)行數(shù)據(jù)庫操作----------end

        // 提交事務(wù)
        transactionManager.commit(transactionStatus);
    } catch (Exception e) {
        e.printStackTrace();
        // 回滾事務(wù)
        transactionManager.rollback(transactionStatus);
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載灸蟆,如需轉(zhuǎn)載請(qǐng)通過簡信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末亲族,一起剝皮案震驚了整個(gè)濱河市炒考,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霎迫,老刑警劉巖票腰,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異女气,居然都是意外死亡杏慰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門炼鞠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缘滥,“玉大人,你說我怎么就攤上這事谒主〕螅” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵霎肯,是天一觀的道長擎颖。 經(jīng)常有香客問我榛斯,道長,這世上最難降的妖魔是什么搂捧? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任驮俗,我火速辦了婚禮,結(jié)果婚禮上允跑,老公的妹妹穿的比我還像新娘王凑。我一直安慰自己,他們只是感情好聋丝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布索烹。 她就那樣靜靜地躺著,像睡著了一般弱睦。 火紅的嫁衣襯著肌膚如雪百姓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天况木,我揣著相機(jī)與錄音瓣戚,去河邊找鬼。 笑死焦读,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舱权。 我是一名探鬼主播矗晃,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宴倍!你這毒婦竟也來了张症?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤鸵贬,失蹤者是張志新(化名)和其女友劉穎俗他,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阔逼,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兆衅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嗜浮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羡亩。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖危融,靈堂內(nèi)的尸體忽然破棺而出畏铆,到底是詐尸還是另有隱情飘诗,我是刑警寧澤惫东,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布劫樟,位于F島的核電站葫盼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瓦灶。R本人自食惡果不足惜鸠删,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倚搬。 院中可真熱鬧冶共,春花似錦、人聲如沸每界。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眨层。三九已至庙楚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間趴樱,已是汗流浹背馒闷。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叁征,地道東北人纳账。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像捺疼,于是被迫代替她去往敵國和親疏虫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容