學(xué)習(xí)框架工具的最好优俘,也是最快的方法就是通過實(shí)例來學(xué)習(xí),本實(shí)例使用spring和mybatis構(gòu)建了一個(gè)java小程序掀序,該程序沒有什么實(shí)際的業(yè)務(wù)功能帆焕,只是通過mybatis簡(jiǎn)單讀取數(shù)據(jù)庫(kù)的數(shù)據(jù)。
一不恭、構(gòu)建數(shù)據(jù)庫(kù)
使用navicat工具連接數(shù)據(jù)庫(kù)后叶雹,創(chuàng)建user表如下:
關(guān)于數(shù)據(jù)庫(kù)表的創(chuàng)建一般要做以下幾點(diǎn):
- 設(shè)定類型:一般常用的類型就是bigint,對(duì)應(yīng)于java中較長(zhǎng)的整型如long换吧;varchar折晦,用于儲(chǔ)存字符串;int 對(duì)應(yīng)java中的integer沾瓦。
- 字段的長(zhǎng)度:指的是字符長(zhǎng)度满着,并不是計(jì)算機(jī)儲(chǔ)存數(shù)據(jù)使用的位的長(zhǎng)度打颤,如root字段長(zhǎng)度為1,則該字段可以填的值為0到9漓滔,這些一位數(shù)编饺。創(chuàng)建表時(shí)字段需要多大就給多長(zhǎng)。
- 字段的其他設(shè)置:在頁面的下方响驴,截圖上沒有透且;包括字段的注釋(描述字段的作用),整型字段要不要設(shè)置為無符號(hào)(如果該字段沒有負(fù)值的話就添上)豁鲤,默認(rèn)值(varchar類型的默認(rèn)值需要用單引號(hào)括起來)
- 外鍵:用于關(guān)聯(lián)多張表的字段秽誊,如另張成績(jī)表上還有一個(gè)字段user_id,該字段的值全部來源于user表上的id字段琳骡,就可以在成績(jī)表上添加外鍵锅论,關(guān)聯(lián)user表上的id字段;
- 表注釋:表的注釋楣号,描述表的用途最易,雖然表名能描述出表的用途,但是如果后面業(yè)務(wù)邏輯變復(fù)雜炫狱,表變得多起來藻懒,添上注釋還是有點(diǎn)好處的,也便于維護(hù)视译。
其他的設(shè)置就和實(shí)際的業(yè)務(wù)有關(guān)了嬉荆;
二、創(chuàng)建maven項(xiàng)目
使用eclipse右擊new - project酷含,選擇maven project鄙早,選擇項(xiàng)目路徑,項(xiàng)目類型選擇椅亚,uqickstart結(jié)尾限番,填寫groupid組名,artifactid項(xiàng)目名什往,finish即可扳缕。
創(chuàng)建maven項(xiàng)目的好處就是不用自己去找jar包,把要用到的jar包寫在配置文件中即可别威,項(xiàng)目會(huì)自動(dòng)引入。創(chuàng)建好的項(xiàng)目后分包如下:
- bean:存放所有bean文件驴剔,數(shù)據(jù)庫(kù)中查詢到的結(jié)果要轉(zhuǎn)換成java對(duì)象省古;
- config:存放所有的spring,mybatis的配置文件丧失;
- dao:存放mybatis連接數(shù)據(jù)庫(kù)要用到的mapper類豺妓;相當(dāng)于存放sql語句的地方;
- mappers:存放mybatis的xml文件,和dao中的文件相對(duì)應(yīng)琳拭。
- util:自定義的工具類训堆;
三、配置文件
使用框架工具最麻煩的就是配置文件了白嘁,不過配置文件也是大同小異坑鱼,可以根據(jù)自己的需要在別人的配置文件上進(jìn)行修改,配置文件寫好后絮缅,業(yè)務(wù)邏輯的代碼就會(huì)變得特別簡(jiǎn)單鲁沥。
1. maven的pom文件
maven的pom文件就是配置要用到的所有jar包的地方,文件內(nèi)容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yesongdh</groupId>
<artifactId>springInstance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springInstance</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.25</slf4j.version>
<springmvc.version>4.3.12.RELEASE</springmvc.version>
<log4j.version>2.8.2</log4j.version>
<mybatis.version>3.4.5</mybatis.version>
<mybatis.spring.version>1.3.1</mybatis.spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- druid數(shù)據(jù)庫(kù)連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency>
<!-- mysql數(shù)據(jù)庫(kù)jdbc驅(qū)動(dòng) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<!-- mybatis數(shù)據(jù)持久化框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--mybatis spring 插件 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- spring框架包 start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${springmvc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springmvc.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.maven/maven-model -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
<!-- 指定項(xiàng)目使用jdk1.7的插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
主要引入了druid數(shù)據(jù)庫(kù)連接池耕魄、mysql數(shù)據(jù)庫(kù)的jdbc驅(qū)動(dòng)画恰、mybatis數(shù)據(jù)庫(kù)持久化框架、spring框架包吸奴;最后一個(gè)是jdk插件允扇,每次建完項(xiàng)目后,項(xiàng)目使用的jdk包都是1.5的则奥,只有在pom文件中添加這一段配置后項(xiàng)目才會(huì)使用jdk1.7或者更新的jdk版本蔼两。
選中項(xiàng)目右擊,選擇maven - update project逞度,把項(xiàng)目刷新一下
2. 配置spring和mybatis框架文件
在config文件夾下創(chuàng)建如下兩個(gè)文件:jdbc.property和mybatis.xml
jdbcs.properties主要是數(shù)據(jù)庫(kù)連接的相關(guān)設(shè)置额划,內(nèi)容如下:
# MySQL
#============================================================================
#test MySQL
jdbc.mysql.driver = com.mysql.jdbc.Driver
jdbc.mysql.url = jdbc:mysql://localhost:3306/test?useSSL=true
jdbc.mysql.username = root
jdbc.mysql.password = SQL1137660
#mybatis config
#============================================================================
jdbc.initialSize = 10
jdbc.minIdle = 10
jdbc.maxActive = 10
jdbc.testWhileIdle = true
jdbc.timeBetweenEvictionRunsMillis = 30000
jdbc.minEvictableIdleTimeMillis = 60000
jdbc.validationQuery = SELECT 'x'
jdbc.testOnBorrow = false
jdbc.testOnReturn = false
jdbc.poolPreparedStatements = true
jdbc.maxOpenPreparedStatements = 100
mybatis.xml文件內(nèi)容如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd ">
<!-- 引入jdbc配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:config/jdbcs.properties" />
</bean>
<!-- 引入aliyun的Druid文件鏈接數(shù)據(jù)庫(kù),并作為數(shù)據(jù)源 -->
<bean id="aliyunDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.mysql.driver}" />
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />
<!-- 初始化連接大小 -->
<property name="initialSize" value="${jdbc.initialSize}" />
<!-- 連接池最大數(shù)量 -->
<property name="maxActive" value="${jdbc.maxActive}" />
<!-- 連接池最小空閑 -->
<property name="minIdle" value="${jdbc.minIdle}" />
<!-- 獲取連接最大等待時(shí)間 -->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
<property name="validationQuery" value="${jdbc.validationQuery}"/>
<property name="testWhileIdle" value="${jdbc.testWhileIdle}"/>
<property name="testOnBorrow" value="${jdbc.testOnBorrow}"/>
<property name="testOnReturn" value="${jdbc.testOnReturn}"/>
<property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}"/>
<property name="maxOpenPreparedStatements" value="${jdbc.maxOpenPreparedStatements}"/>
</bean>
<!-- spring和MyBatis的整合 -->
<bean id="aliyunSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="aliyunDataSource" />
<!-- 自動(dòng)掃描mapping.xml文件档泽,**表示迭代查找俊戳,目錄結(jié)構(gòu)改變需要變動(dòng) -->
<property name="mapperLocations" value="classpath:mappers/*.xml" />
</bean>
<!-- DAO接口所在包名,Spring會(huì)自動(dòng)查找其下的類 ,包下的類需要使用@MapperScan注解,否則容器注入會(huì)失敗 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="dao" /><!-- 目錄結(jié)構(gòu)改變需要變動(dòng) -->
<property name="sqlSessionFactoryBeanName" value="aliyunSqlSessionFactory" />
</bean>
<!--事務(wù)管理器 spring事務(wù)管理器馆匿,推薦使用 -->
<bean id="aliyunTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="aliyunDataSource"/>
</bean>
<!-- 啟動(dòng)事務(wù)注解 -->
<tx:annotation-driven transaction-manager="aliyunTransactionManager"/>
</beans>
mybatis.xml主要是設(shè)置數(shù)據(jù)庫(kù)的數(shù)據(jù)源抑胎、引入所有mybatis 的dao文件和xml文件、使用spring事務(wù)管理渐北。
四阿逃、業(yè)務(wù)代碼
1. 創(chuàng)建bean文件和dao文件
- 在bean文件夾下創(chuàng)建user.java;內(nèi)容如下:
public class User {
private String id;
private String name;
private int sex;
private String phone;
private String email;
private int root;
private String password;
后半部分全是字段的get/set方法赃蛛,還有改寫的tostring方法用于觀察最后的打印結(jié)構(gòu)恃锉,就不貼出來了。
關(guān)于bean類要注意:
bean類所有字段的名稱一定要和查詢語句的字段名對(duì)應(yīng)呕臂;如:select user_id, name from score; 選取了數(shù)據(jù)庫(kù)score表的user_id和name字段破托,這些字段都要填充到user.java類中,那user.java中的字段名必須為user_id和name歧蒋,不然最后得到的user對(duì)象的id字段肯定為空土砂≈菁龋或者更改sql語句為select user_id as id, name from score;給數(shù)據(jù)庫(kù)字段別名萝映∥庖叮框架可能使用了反射,讀取了java對(duì)象的所有字段名序臂,根據(jù)字段名和數(shù)據(jù)庫(kù)的查詢結(jié)果字段名一一對(duì)應(yīng)蚌卤,最后通過get和set方法個(gè)java對(duì)象的字段賦值。
- 在dao文件夾下創(chuàng)建dao文件贸宏,文件類型為接口造寝,UserMapper.java,內(nèi)容如下:
@MapperScan
public interface UserMapper {
@Select("select id, name, sex, phone, email, root, password from user")
List<User> getUsers();
}
注意那個(gè)@mapperscan注解和@select注解吭练,mybatis就是掃描那兩個(gè)注解把文件掃描進(jìn)springcontext中的诫龙。查詢結(jié)果如果不止一個(gè)的話就需要用list,如果只有一個(gè)那就填User類型鲫咽。
其實(shí)所有的sql語句也可以寫在mappers包的xml中签赃,和dao包這個(gè)的類進(jìn)行關(guān)聯(lián)。如果要對(duì)sql語句的復(fù)用的話可能就需要把sql語句寫在xml文件中比較好分尸,不過我更傾向于寫在dao文件中锦聊,寫代碼的時(shí)候就可以少打開一個(gè)窗口,更方便箩绍。
- 在mappers目錄創(chuàng)建UserMapper.xml文件孔庭,內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.UserMapper">
</mapper>
sql語句可以寫在這里,和dao包中的文件通過這里的namespace聯(lián)系起來材蛛,dao包中只提供接口方法圆到,這里提供sql;不過也可以像我一樣通過注解的方式卑吭,把sql語句寫在dao包里芽淡,這里就可以什么都不用寫。在修改時(shí)就不用同時(shí)打開三個(gè)文件了豆赏。
2. App業(yè)務(wù)代碼
app中的代碼如下:
public class App
{
public static void main( String[] args )
{
ApplicationContext context = new ClassPathXmlApplicationContext("config/mybatis.xml");
UserMapper userMapper = context.getBean(UserMapper.class);
List<User> users = userMapper.getUsers();
System.out.println(users);
}
}
打印結(jié)果如下:
五挣菲、打包成可執(zhí)行文件
java引用程序可以被打包成可執(zhí)行 jar 文件,eclipse右擊選擇export掷邦,選擇 runnable JAR file白胀,在launch config 中選擇包含main方法的類,下面是三種對(duì)于引用的庫(kù)的處理方式:把需要的jar包都抽取到生成的jar文件中耙饰,打包所有需要的庫(kù)文件到生成的jar文件中纹笼,復(fù)制需要的庫(kù)文件到子目錄中;這里選擇最后一個(gè)苟跪;然后finish就可以了廷痘。
jar文件所在位置,shift + 右擊運(yùn)行power shell件已,輸入 java -jar ./springInstance.jar笋额,運(yùn)行結(jié)果如下,和eclipse的運(yùn)行結(jié)果相同:
六篷扩、總結(jié)
整理一下整個(gè)程序的邏輯流程:
在主程序中ClassPathXmlApplicationContext("config/mybatis.xml")兄猩;讀取spring的配置文件,配置文件主要做了三件事:
- 使用com.alibaba.druid.pool.DruidDataSource建立線程池?cái)?shù)據(jù)源鉴未;
- mybatis 掃描mappers文件夾下的mapper.xml文件和dao包下的dao文件枢冤,將掃描到的文件加入到spring配置文件中;
- 事務(wù)管理器和事務(wù)注解管理铜秆;其實(shí)還可以加入一些從程序一開始就需要運(yùn)行的初始化程序淹真。
最后主程序從applicationContext中獲取dao包中的初始化好的實(shí)例,調(diào)用dao方法连茧。
個(gè)人理解spring是另一種寫代碼的風(fēng)格核蘸,用配置文件的方式來實(shí)例化對(duì)象,所有配置文件中的類都可以在applicationContext中找到啸驯,很方便客扎。spring和mybatis的配合,mybatis通過掃描注解和文件的方式罚斗,把所有的數(shù)據(jù)庫(kù)連接對(duì)象都添加到spring中進(jìn)行實(shí)例化徙鱼,在編寫業(yè)務(wù)代碼時(shí)就可以直接在applicationContex對(duì)象中獲取,有效地減少了業(yè)務(wù)代碼量针姿。
源碼下載:https://pan.baidu.com/s/1fYTIzsT6xpmyjsNZCvlwfg
如果有不對(duì)的地方歡迎指正討論