第四章訪問(wèn)數(shù)據(jù)庫(kù)-Springboot3視頻筆記

動(dòng)力節(jié)點(diǎn)王鶴老師springboot3視頻第四章

4 訪問(wèn)數(shù)據(jù)庫(kù)

Spring Boot框架為SQL數(shù)據(jù)庫(kù)提供了廣泛的支持秫逝,既有用JdbcTemplate直接訪問(wèn)JDBC寸爆,同時(shí)支持“object relational mapping”技術(shù)(如Hibernate源哩,MyBatis)知态。Spring Data獨(dú)立的項(xiàng)目提供對(duì)多種關(guān)系型和非關(guān)系型數(shù)據(jù)庫(kù)的訪問(wèn)支持鸳君。比如 MySQL, Oracle , MongoDB , Redis, R2DBC倒得,Apache Solr泻红,Elasticsearch...

Spring Boot也支持嵌入式數(shù)據(jù)庫(kù)比如H2, HSQL, and Derby。這些數(shù)據(jù)庫(kù)只需要提供jar包就能在內(nèi)存中維護(hù)數(shù)據(jù)霞掺。我們這章訪問(wèn)關(guān)系型數(shù)據(jù)庫(kù)谊路。

4.1 DataSource

通常項(xiàng)目中使用MySQL,Oracle,PostgreSQL等大型關(guān)系數(shù)據(jù)庫(kù)。Java中的jdbc技術(shù)支持了多種關(guān)系型數(shù)據(jù)庫(kù)的訪問(wèn)根悼。在代碼中訪問(wèn)數(shù)據(jù)庫(kù)凶异,我們需要知道數(shù)據(jù)庫(kù)程序所在的ip,端口挤巡,訪問(wèn)數(shù)據(jù)庫(kù)的用戶名和密碼以及數(shù)據(jù)庫(kù)的類型信息。以上信息用來(lái)初始化數(shù)據(jù)源酷麦,數(shù)據(jù)源也就是DataSource矿卑。數(shù)據(jù)源表示數(shù)據(jù)的來(lái)源,從某個(gè)ip上的數(shù)據(jù)庫(kù)能夠獲取數(shù)據(jù)沃饶。javax.sql.DataSource接口表示數(shù)據(jù)源母廷,提供了標(biāo)準(zhǔn)的方法獲取與數(shù)據(jù)庫(kù)綁定的連接對(duì)象(Connection)。

javax.sql.Connection是連接對(duì)象糊肤,在Connection上能夠從程序代碼發(fā)送查詢命令琴昆,更新數(shù)據(jù)的語(yǔ)句給數(shù)據(jù)庫(kù);同時(shí)從Connection獲取命令的執(zhí)行結(jié)果馆揉。Connection很重要业舍,像一個(gè)電話線把應(yīng)用程序和數(shù)據(jù)庫(kù)連接起來(lái)。


DataSource在application配置文件中以spring.datasource.*作為配置項(xiàng)升酣。類似下面的代碼:

spring.datasource.url=jdbc:mysql://localhost/mydb

spring.datasource.username=dbuser

spring.datasource.password=dbpass

DataSourceProperties.java是數(shù)據(jù)源的配置類舷暮,更多配置參考這個(gè)類的屬性。

Spring Boot能夠從spring.datasource.url推斷所使用的數(shù)據(jù)驅(qū)動(dòng)類噩茄,如果需要特殊指定請(qǐng)?jiān)O(shè)置spring.datasource.driver-class-name為驅(qū)動(dòng)類的全限定名稱下面。

Spring Boot支持多種數(shù)據(jù)庫(kù)連接池,優(yōu)先使用 HikariCP绩聘,其次是Tomcat pooling沥割,再次是 Commons DBCP2耗啦,如果以上都沒(méi)有,最后會(huì)使用Oracle UCP連接池机杜。當(dāng)項(xiàng)目中starter依賴了spring-boot-starter-jdbc 或者spring-boot-starter-data-jpa默認(rèn)添加HikariCP連接池依賴芹彬,也就是默認(rèn)使用HikariCP連接池。

4.2 輕量的JdbcTemplate

使用JdbcTemplate我們提供自定義SQL, Spring執(zhí)行這些SQL得到記錄結(jié)果集叉庐。JdbcTemplate和NamedParameterJdbcTemplate類是自動(dòng)配置的舒帮,您可以@Autowire注入到自己的Bean中。開箱即用陡叠。

JdbcTemplate執(zhí)行完整的SQL語(yǔ)句玩郊,我們將SQL語(yǔ)句拼接好,交給JdbcTemplate執(zhí)行枉阵,JdbcTemplate底層就是使用JDBC執(zhí)行SQL語(yǔ)句译红。是JDBC的封裝類而已。

NamedParameterJdbcTemplate可以在SQL語(yǔ)句部分使用“:命名參數(shù)”作為占位符, 對(duì)參數(shù)命名兴溜,可讀性更好侦厚。NamedParameterJdbcTemplate包裝了JdbcTemplate對(duì)象,“:命名參數(shù)”解析后拙徽,交給JdbcTemplate執(zhí)行SQL語(yǔ)句刨沦。

JdbcTemplateAutoConfiguration自動(dòng)配置了JdbcTemplate對(duì)象,交給JdbcTemplateConfiguration創(chuàng)建了JdbcTemplate對(duì)象膘怕。并對(duì)JdbcTemplate做了簡(jiǎn)單的初始設(shè)置(QueryTimeout想诅,maxRows等)。

4.2.1 準(zhǔn)備環(huán)境

訪問(wèn)數(shù)據(jù)庫(kù)先準(zhǔn)備數(shù)據(jù)庫(kù)的script岛心。SpringBoot能夠自動(dòng)執(zhí)行DDL来破,DML腳本。兩個(gè)腳本文件名稱默認(rèn)是schema.sql和data.sql忘古。腳本文件在類路徑中自動(dòng)加載徘禁。

自動(dòng)執(zhí)行腳本還涉及到spring.sql.init.mode配置項(xiàng):

[if !supportLists]·?[endif]always:總是執(zhí)行數(shù)據(jù)庫(kù)初始化腳本

[if !supportLists]·?[endif]never:禁用數(shù)據(jù)庫(kù)初始化

更進(jìn)一步

Spring Boot處理特定的數(shù)據(jù)庫(kù)類型,為特定的數(shù)據(jù)庫(kù)定制script文件髓堪。首先設(shè)置spring.sql.init.platform=hsqldb送朱、h2、oracle旦袋、mysql骤菠、postgresql等等,其次準(zhǔn)備 schema-${platform}. sql 疤孕、 data-${platform}. sql 腳本文件商乎。

4.2.1.1 準(zhǔn)備數(shù)據(jù)庫(kù)和表腳本

首先創(chuàng)建數(shù)據(jù)庫(kù),安裝MySQL8.5祭阀。有可用的MySQL數(shù)據(jù)庫(kù)就可以鹉戚,最好是5以上版本鲜戒。

數(shù)據(jù)庫(kù)名稱Blog , 表目前使用一個(gè) article(文章表)抹凳,初始兩條數(shù)據(jù)遏餐。

schema.sql

CREATE?TABLE?`article`?(

`id`?int(11)NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',

`user_id`?int(11)NOT?NULL?COMMENT?'作者ID',

`title`?varchar(100)NOT?NULL?COMMENT?'文章標(biāo)題',

`summary`?varchar(200)DEFAULT?NULL?COMMENT?'文章概要',

`read_count`?int(11)unsigned?zerofill?NOT?NULL?COMMENT?'閱讀讀數(shù)',

`create_time`datetime?NOT?NULL?COMMENT?'創(chuàng)建時(shí)間',

`update_time`datetime?NOT?NULL?COMMENT?'最后修改時(shí)間',

PRIMARY?KEY?(`id`))ENGINE=InnoDB?AUTO_INCREMENT=1?DEFAULT?CHARSET=utf8mb4;

data.sql

INSERT?INTO?`article`VALUES?('1','2101','SpringBoot核心注解',

'核心注解的主要作用','00000008976','2023-01-16?12:11:12','2023-01-16?12:11:19');

INSERT?INTO?`article`VALUES?('2','356752','JVM調(diào)優(yōu)',

'HotSpot虛擬機(jī)詳解','00000000026','2023-01-16?12:15:27','2023-01-16?12:15:30');

4.2.1.2 創(chuàng)建Spring Boot工程

新建Spring Boot工程Lession09-JdbcTemplate

構(gòu)建工具:Maven

包名:com.bjpowernode.jdbc

JDK:19

Starter依賴:Lombok,MySQL Driver, JDBC API

Maven依賴(pom.xml)

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jdbc</artifactId>

<groupId>com.mysql</groupId>

<artifactId>mysql-connector-j</artifactId>

<scope>runtime</scope>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

IDEA Maven Tool查看依賴列表


依賴包含了連接池com.zaxxer:HikariCP:5.0.1 , spring-jdbc 6.0.3 , mysql驅(qū)動(dòng)mysql-connector-j 8.0.31赢底。

4.2.2 JdbcTemplate訪問(wèn)MySQL

項(xiàng)目中依賴了spring-jdbc 6.0.3失都,JdbcTemplate對(duì)象會(huì)自動(dòng)創(chuàng)建好。把JdbcTemplate對(duì)象注入給你的Bean幸冻,再調(diào)用JdbcTemplate的方法執(zhí)行查詢粹庞,更新,刪除的SQL洽损。

JdbcTemplate上手快庞溜,功能非常強(qiáng)大。提供了豐富碑定、實(shí)用的方法流码,歸納起來(lái)主要有以下幾種類型的方法:

(1)execute方法:可以用于執(zhí)行任何SQL語(yǔ)句,常用來(lái)執(zhí)行DDL語(yǔ)句延刘。

(2)update漫试、batchUpdate方法:用于執(zhí)行新增、修改與刪除等語(yǔ)句访娶。

(3)query和queryForXXX方法:用于執(zhí)行查詢相關(guān)的語(yǔ)句商虐。

(4)call方法:用于執(zhí)行數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程和函數(shù)相關(guān)的語(yǔ)句。

我們?cè)?.2.1.2已經(jīng)創(chuàng)建了Spring Boot工程崖疤,在工程上繼續(xù)添加代碼,完成對(duì)Blog庫(kù)典勇,article表的CRUD劫哼。

step1:將schema.sql , data.sql拷貝到resources目錄


step2:修改application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false

spring.datasource.username=root

spring.datasource.password=123456

#總是執(zhí)行數(shù)據(jù)庫(kù)腳本,以后設(shè)置為never

spring.sql.init.mode=always

step3: 創(chuàng)建實(shí)體類 ArticlePO

Lomok注解給類的屬性生成set割笙,get方法权烧。 默認(rèn)和所有參數(shù)構(gòu)造方法

step4: 單元測(cè)試,注入JdbcTemplate對(duì)象

@SpringBootTest

public class TestJdbcTemplate {

@Resource

?private JdbcTemplate jdbcTemplate;

}

測(cè)試聚合函數(shù)

@Test

void testCount() {

?String sql="select count(*) as ct from article";

?Long count = jdbcTemplate.queryForObject(sql, Long.class);

System.out.println("文章總數(shù) = " + count);??

}

測(cè)試“?”占位符

@Test

void testQuery() {

?// 伤溉?作為占位符

?String sql = "select * from article where id= ? ";

?//BeanPropertyRowMapper 將查詢結(jié)果集般码,列名與屬性名稱匹配, 名稱完全匹配或駝峰

?ArticlePO article = jdbcTemplate.queryForObject(sql,

?new BeanPropertyRowMapper<>(ArticlePO.class), 1 );

System.out.println("查詢到的文章 = " + article);?

}

測(cè)試自定義RowMapper

測(cè)試List集合

@Test

void testList() {

?String sql="select * from article order by id ";

?List> listMap = jdbcTemplate.queryForList(sql);

?listMap.forEach( el->{

?el.forEach( (field,value)->{????????

System.out.println("字段名稱:"+field+"乱顾,列值:"+value);??????

});

?System.out.println("===================================");????

});

}

測(cè)試更新記錄

@Test

void testUpdate() {

?String sql="update article set title = ? where id= ? ";

?//參數(shù)是從左往右 第一個(gè)板祝,第二個(gè)...

int updated = jdbcTemplate.update(sql, "Java核心技術(shù)思想", 2);????

System.out.println("更新記錄:"+updated);??

}

4.2.3 NamedParameterJdbcTemplate

NamedParameterJdbcTemplate能夠接受命名的參數(shù),通過(guò)具名的參數(shù)提供代碼的可讀性走净,JdbcTemplate使用的是參數(shù)索引的方式券时。

在使用模板的位置注入NamedParameterJdbcTemplate對(duì)象孤里,編寫SQL語(yǔ)句,在SQL中WHERE部分“:命名參數(shù)”橘洞。調(diào)用NamedParameterJdbcTemplate的諸如query捌袜,queryForObject, execute,update等時(shí),將參數(shù)封裝到Map中炸枣。

step1:注入模板對(duì)象

@Resource

private?JdbcTemplate jdbcTemplate;

step2: 使用命名參數(shù)

@Test

void testNameQuery() {

?// :參數(shù)名

?String sql="select count(*) as ct from article where user_id=:uid and read_count > :num";

//key是命名參數(shù)

?Map param = new HashMap<>();

?param.put("uid", 2101);

?param.put("num", 0);????

?Long count = nameJdbcTemplate.queryForObject(sql, param, Long.class);

?System.out.println("用戶被閱讀的文章數(shù)量 = " + count);

}

4.2.4 多表查詢

多表查詢關(guān)注是查詢結(jié)果如何映射為Java Object虏等。常用兩種方案:一種是將查詢結(jié)果轉(zhuǎn)為Map。列名是key适肠,列值是value霍衫,這種方式比較通用,適合查詢?nèi)魏伪碛睾铩5诙N是根據(jù)查詢結(jié)果中包含的列慕淡,創(chuàng)建相對(duì)的實(shí)體類。屬性和查詢結(jié)果的列對(duì)應(yīng)沸毁。將查詢結(jié)果自定義RowMapper峰髓、ResultSetExtractor映射為實(shí)體類對(duì)象。

現(xiàn)在創(chuàng)建新的表article_detail息尺,存儲(chǔ)文章內(nèi)容携兵,與article表是一對(duì)一關(guān)系。


article_detail表

CREATE?TABLE?`article_detail`?(

?`id`?int(11)?NOT?NULL?AUTO_INCREMENT?COMMENT?'注解',

?`article_id`?int(11)?NOT?NULL?COMMENT?'文章ID',

?`content`?text?NOT?NULL?COMMENT?'文章內(nèi)容',

?PRIMARY?KEY?(`id`))?

ENGINE=InnoDB?AUTO_INCREMENT=1?DEFAULT?CHARSET=utf8mb4;

需求:查詢某個(gè)文章的全部屬性搂誉,包括文章內(nèi)容

step1:創(chuàng)建新的實(shí)體類ArticleMainPO, 將ArticlePO作為成員變量

@Data

@NoArgsConstructor

@AllArgsConstructor

public class ArticleMainPO {

?private Integer id;

?private Integer userId;

?private String title;

?private String summary;

?private Integer readCount;

?private LocalDateTime createTime;

?private LocalDateTime updateTime;

?private ArticleDetailPO articleDetail;

}

step2: 查詢一對(duì)一文章

@Test

void testArticleContent() {

?String sql= """

?select m.*,d.id as detail_id, d.article_id,d.content

?from article m join article_detail d

?on m.id = d.article_id

?where m.id=:id

?""";

?Map param = new HashMap<>();

?param.put("id", 1);

?List list = nameJdbcTemplate.query(sql, param, (rs, rowNum) -> {

?var id = rs.getInt("id");

?var userId = rs.getInt("user_id");

?var title = rs.getString("title");

?var summary = rs.getString("summary");

?var readCount = rs.getInt("read_count");

?var createTime = new Timestamp(rs.getTimestamp("create_time").getTime())

.toLocalDateTime();

?var updateTime = new Timestamp(rs.getTimestamp("update_time").getTime())

.toLocalDateTime();

?//文章詳情

?var detailId = rs.getInt("detail_id");

?var content = rs.getString("content");

?var articleId = rs.getInt("article_id");

?ArticleDetailPO detail = new ArticleDetailPO();

?detail.setId(detailId);

?detail.setArticleId(articleId);

?detail.setContent(content);

?return new ArticleMainPO(id, userId, title, summary, readCount,

?createTime, updateTime, detail);

?});

?list.forEach(m -> {

?System.out.println("m.getId() = " + m.getId());

?System.out.println("m.getArticleDetail() = " + m.getArticleDetail());

?});

}

總結(jié):

JdbcTemplate的優(yōu)點(diǎn)簡(jiǎn)單徐紧,靈活,上手快炭懊,訪問(wèn)多種數(shù)據(jù)庫(kù)并级。對(duì)數(shù)據(jù)的處理控制能力比較強(qiáng),RowMapper, ResultSetExtractor能夠提供按需要靈活定制記錄集與實(shí)體類的關(guān)系侮腹。

缺點(diǎn):對(duì)SQL要求高嘲碧,適合對(duì)SQL比較了解,自定義查詢結(jié)果比較多父阻,調(diào)優(yōu)需求的愈涩。

JdbcTemplate對(duì)象的調(diào)整參數(shù),比較少加矛÷耐瘢可設(shè)置spring.jdbc.template.開頭的配置項(xiàng)目,比如設(shè)置超時(shí)為10秒斟览,spring.jdbc.template.query-timeout=10毁腿。

4.3 MyBatis

數(shù)據(jù)庫(kù)訪問(wèn)MyBatis,MyBatis-Plus國(guó)內(nèi)很常用,掌握了MyBatis狸棍,MyBatis-Plus就會(huì)了大部分了身害。MyBatis-Plus附加的功能需要單獨(dú)學(xué)習(xí)。我們以MyBatis來(lái)自介紹Spring Boot集成ORM框架草戈。

MyBatis使用最多的是mapper xml文件編寫SQL語(yǔ)句塌鸯。本章使用MyBatis的注解,JDK新特性文本塊唐片,以及Record完成java對(duì)象和表數(shù)據(jù)的處理丙猬。

4.3.1 單表CRUD

首先向blog數(shù)據(jù)庫(kù)的article表添加新的文章,以及修改费韭,查詢文章茧球。在新工程Lession10-MyBatis集成MyBatis框架。項(xiàng)目包名com.bjpowernode.orm星持。依賴需要mysql驅(qū)動(dòng)抢埋、mybatis依賴,Lombok督暂。


step1: Maven依賴

step2:創(chuàng)建實(shí)體類

//PO:Persistent Object@Datapublic class ArticlePO { private Integer id; private Integer userId; private String title; private String summary; private Integer readCount; private LocalDateTime createTime; private LocalDateTime updateTime;}

step3: 創(chuàng)建Mapper接口

public interfaceArticleMapper { String field_list="id,user_id,title,summary,read_count,create_time,update_time"; @Insert(""" insert into article(user_id,title,summary,read_count,create_time,update_time) \?values(#{userId},#{title},#{summary},#{readCount},#{createTime},#{updateTime}) """) int insertArticle(ArticlePO article); @Update(""" update article set read_count=#{num} where id=#{id} """) int updateReadCount(Integer id,Integer num); @Delete(""" delete from article where id=#{id} """) int deleteById(Integer id); @Select("select " + field_list + " from article where id=#{articleId}") @Results({ @Result(id = true,column = "id",property = "id"), @Result(column = "user_id",property = "userId"), @Result(column = "read_count",property = "readCount"), @Result(column = "create_time",property = "createTime"), @Result(column = "update_time",property = "updateTime"), }) ArticlePO selectById(@Param("articleId") Integer id);}

@Results部分為結(jié)果映射(XML中的<ResultMap>), 或者用MyBatis的駝峰命名也能實(shí)現(xiàn)默認(rèn)的映射關(guān)系揪垄。

application.properties

#駝峰,下劃線命名mybatis.configuration.map-underscore-to-camel-case=true

step4: 啟動(dòng)類加入掃描注解

@MapperScan({"com.bjpowernode.orm.repository"})@SpringBootApplicationpublic class Lession10MyBatisApplication { public static void main(String[] args) { SpringApplication.run(Lession10MyBatisApplication.class, args); }}

@MapperScan是掃描注解逻翁,參數(shù)是Mapper接口所在的包名饥努。參數(shù)是數(shù)組,可以指定多個(gè)包位置八回。

step5: 配置數(shù)據(jù)源

application.properties或yml都可以

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=falsespring.datasource.username=rootspring.datasource.password=123456#駝峰酷愧,下劃線命名mybatis.configuration.map-underscore-to-camel-case=true

step6:單元測(cè)試

@SpringBootTestclass Lession10MyBatisApplicationTests {

?@Autowired private ArticleMapper articleMapper;

?@Test void testInsert() { ArticlePO article = new ArticlePO(); article.setTitle("什么時(shí)候用微服務(wù)"); article.setSummary("微服務(wù)優(yōu)缺點(diǎn)"); article.setUserId(219); article.setReadCount(560); article.setCreateTime(LocalDateTime.now()); article.setUpdateTime(LocalDateTime.now()); articleMapper.insertArticle(article); } @Test void testUpdate() { int rows = articleMapper.updateReadCount(1, 230); System.out.println("修改的記錄數(shù)量:" + rows); } @Test void testDelete(){ int rows = articleMapper.deleteById(11); System.out.println("刪除記錄的數(shù)量 " + rows); } @Test void testSelect(){ ArticlePO articlePO = articleMapper.selectById(3); System.out.println("查詢到的文章:" + articlePO); }}

4.3.2 ResultMap

查詢操作得到包含多個(gè)列的集合,將列值轉(zhuǎn)為對(duì)象屬性使用結(jié)果映射的功能缠诅,注解@Results溶浴,@ResultMap能夠幫助我們完成此功能。

@Results用于定義結(jié)果映射管引,每個(gè)列和Java對(duì)象屬性的一一對(duì)應(yīng)戳葵。

@ResultMap 指定使用哪個(gè)結(jié)果映射,兩種方式可以使用@Results汉匙,另一種XML文件。

需求:執(zhí)行多個(gè)select語(yǔ)句生蚁,使用結(jié)果映射轉(zhuǎn)換數(shù)據(jù)庫(kù)記錄為Java Object噩翠。

step1:創(chuàng)建新的Mapper對(duì)象。

public interfaceArticleDao { //定義mapper, id表示唯一名稱 @Select("") @Results(id = "BaseMapper", value = { @Result(id = true, column = "id", property = "id"), @Result(column = "user_id", property = "userId"), @Result(column = "read_count", property = "readCount"), @Result(column = "create_time", property = "createTime"), @Result(column = "update_time", property = "updateTime"), }) ArticlePO articleMapper(); @Select(""" select id,user_id,title,summary,read_count,create_time,update_time?from article whereuser_id=${userId} """) @ResultMap("BaseMapper") List<ArticlePO> selectList(Integer userId); @Select(""" select id,user_id,title,summary,read_count,create_time,update_time?from article whereid=#{articleId} """) @ResultMap("BaseMapper")?ArticlePO selectById(@Param("articleId") Integer id);}

@Results的id定義當(dāng)前結(jié)果映射的唯一名稱邦投, 后面內(nèi)容是列和屬性的一一映射說(shuō)明伤锚。

其他的查詢方法@ResultMap引用@Results的id。使用BaseMapper的映射規(guī)則處理查詢結(jié)果志衣。

step2: 單元測(cè)試

@SpringBootTestpublic class ArticleDaoTest { @Autowired private ArticleDao articleDao; @Test void testSelectList() { List<ArticlePO> poList = articleDao.selectList(219); poList.forEach(po -> { System.out.println("po = " + po); }); } @Test void testSelect(){ ArticlePO articlePO = articleDao.selectById(1); System.out.println("查詢到的文章:" + articlePO); }}

另一種方法在xml中定義標(biāo)簽屯援,在@ResultMap注解引用猛们。 這種方式首先創(chuàng)建xml。在resources目錄下創(chuàng)建自定義的mapper目錄狞洋。 新建ArticleMapper.xml 弯淘。


ArticleMapper.xml 代碼清單:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吉懊,隨后出現(xiàn)的幾起案子庐橙,更是在濱河造成了極大的恐慌,老刑警劉巖借嗽,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件态鳖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恶导,警方通過(guò)查閱死者的電腦和手機(jī)浆竭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惨寿,“玉大人邦泄,你說(shuō)我怎么就攤上這事$吐伲” “怎么了虎韵?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缸废。 經(jīng)常有香客問(wèn)我包蓝,道長(zhǎng),這世上最難降的妖魔是什么企量? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任测萎,我火速辦了婚禮,結(jié)果婚禮上届巩,老公的妹妹穿的比我還像新娘硅瞧。我一直安慰自己,他們只是感情好恕汇,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布腕唧。 她就那樣靜靜地躺著,像睡著了一般瘾英。 火紅的嫁衣襯著肌膚如雪枣接。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天缺谴,我揣著相機(jī)與錄音但惶,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛膀曾,可吹牛的內(nèi)容都是我干的县爬。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼添谊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼财喳!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起碉钠,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纲缓,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后喊废,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祝高,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年污筷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了工闺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓣蛀,死狀恐怖陆蟆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惋增,我是刑警寧澤叠殷,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站诈皿,受9級(jí)特大地震影響林束,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稽亏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一壶冒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧截歉,春花似錦胖腾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至宵睦,卻和暖如春性宏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背状飞。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诬辈。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓酵使,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親焙糟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子口渔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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