MyBatis增刪改查和配置文件
MyBatis增刪改查

MyBatis新增

新增用戶
-
持久層接口添加方法
void add(User user); -
映射文件添加標簽
<insert id="add" parameterType="com.mybatis.pojo.User"> insert into user(username,sex,address) values(# {username},# {sex},# {address}) </insert> -
編寫測試方法
@Test public void testAdd() throws Exception { InputStream is= Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); SqlSession session = factory.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User("程序員", "男", "上海"); userMapper.add(user); // 提交事務 session.commit(); session.close(); is.close(); }
注意:
- 當接口方法的參數類型為POJO類型時,SQL語句中綁定參數時使用
# {POJO的屬性名}即可。- MyBatis事務默認手動提交,所以在執行完增刪改方法后,需要手動調用SqlSession對象的事務提交方法,否則數據庫將不發生改變。
MyBatis修改
優化測試類
我們發現MyBatis的測試方法在操作數據庫前都需要獲取代理對象,操作數據庫后都需要釋放資源,可以利用Junit的前置后置方法,優化測試類代碼。
InputStream is = null;
SqlSession session = null;
UserMapper userMapper = null;
@Before
public void before() throws IOException {
// (1)讀取核心配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
// (2)創建SqlSessionFactoryBuilder對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// (3)SqlSessionFactoryBuilder對象獲取SqlSessionFactory對象
SqlSessionFactory factory = builder.build(is);
// (4)SqlSessionFactory對象獲取SqlSession對象
session = factory.openSession();
// (5)獲取代理對象
userMapper = session.getMapper(UserMapper.class);
}
@After
public void after() throws IOException {
// 釋放資源
session.close();
is.close();
}
這樣Junit就會自動執行獲取代理對象和釋放資源的方法。
修改用戶
-
持久層接口添加方法
void update(User user); -
映射文件添加標簽
<update id="update" parameterType="com.mybatis.pojo.User"> update user set username = #{username}, sex = #{sex}, address=#{address} where id = #{id} </update> -
編寫測試方法
@Test public void testUpdate(){ User user = new User(8,"程序員1","女","深圳"); userMapper.update(user); session.commit(); }
MyBatis刪除、根據Id查詢
刪除用戶
-
持久層接口添加方法
void delete(int userId); -
映射文件添加標簽
<delete id="delete" parameterType="int"> delete from user where id = #{id} </delete>注:當方法的參數類型是簡單數據類型時,#{}中可以寫任意名稱
- 簡單數據類型:基本數據類型、字符串等
-
編寫測試方法
@Test public void testDelete(){ userMapper.delete(8); session.commit(); }
根據ID查詢用戶
-
持久層接口添加方法
User findById(int userId); -
映射文件添加標簽
<select id="findById" parameterType="int" resultType="com.mybatis.pojo.User"> select * from user where id = #{userId} </select> -
編寫測試方法
@Test public void testFindById(){ User user = userMapper.findById(1); System.out.println(user); }
MyBatis模糊查詢
使用#定義參數
-
持久層接口添加方法
List<User> findByNameLike(String username); -
映射文件添加標簽
<select id="findByNameLike" parameterType="string" resultType="com.mybatis.user.User"> select * from user where username like #{name} </select> -
編寫測試方法
@Test public void testFindByNameLike(){ List<User> users = userMapper.findByNameLike("%王%"); for (User user:users){ System.out.println(user); } }
我們看到在映射文件中,parameterType的值為
string而沒有寫java.lang.String,這是為什么呢?
- 參數/返回值類型為基本數據類型/包裝類/String等類型時,我們可以寫全類名,也可以寫別名。
| 數據類型 | 別名 |
|---|---|
| byte | _byte |
| long | _long |
| short | _short |
| int | _int |
| int | _integer |
| double | _double |
| float | _float |
| boolean | _boolean |
| String | string |
| Byte | byte |
| Long | long |
| Short | short |
| Integer | int/integer |
| Double | double |
| Float | float |
| Boolean | boolean |
| Date | date |
| BigDecimal | decimal/bigdecimal |
| Object | object |
| Map | map |
| HashMap | hashmap |
| List | list |
| ArrayList | arraylist |
| Collection | collection |
| Iterator | iterator |
使用$定義參數
模糊查詢如果不想在調用方法時參數加%,可以使用拼接參數的方式設置Sql:
<select id="findByUsernameLike" parameterType="string" resultType="com.mybatis.pojo.User">
select * from user where username like '%${value}%'
</select>
測試方法寫法如下:
@Test
public void testFindByNameLike(){
List<User> users = userMapper.findByUsernameLike("張三");
users.forEach(System.out::println);
}
#和$的區別:
- #表示sql模板的占位符,$表示將字符串拼接到sql模板中。
- #可以防止sql注入,一般能用#就不用$。
- ${}內部的參數名必須寫value。
使用< bind>定義參數
如果使用#還不想在調用方法的參數中添加%,可以使用<bind>標簽,<bind>標簽允許我們在 Sql語句以外創建一個變量,并可以將其綁定到當前的Sql語句中。用法如下:
<select id="findByUsernameLike" parameterType="string" resultType="com.mybatis.pojo.User">
<bind name="likeName" value="'%'+username+'%'"/>
select * from user where username like #{likeName}
</select>
測試方法寫法如下:
@Test
public void testFindByNameLike(){
List<User> users = userMapper.findByUsernameLike("張三");
users.forEach(System.out::println);
}
MyBatis分頁查詢
分頁查詢時,Sql語句使用limit關鍵字,需要傳入開始索引和每頁條數兩個參數。MyBatis的多參數處理有以下方式:
順序傳參
Sql中的參數使用arg0,arg1…或param1,param2…表示參數的順序。此方法可讀性較低,在開發中不建議使用。
-
持久層接口方法
/** * 分頁查詢 * @param startIndex 開始索引 * @param pageSize 每頁條數 * @return */ List<User> findPage(int startIndex,int pageSize); -
映射文件
<select id="findPage" resultType="com.mybatis.mapper.User"> select * from user limit #{arg0},#{arg1} </select> <select id="findPage" resultType="com.mybatis.mapper.User"> select * from user limit #{param1},#{param2} </select> -
測試類
@Test public void testFindPage(){ List<User> users = userMapper.findPage(0,3); users.forEach(System.out::println); }
@Param傳參
在接口方法的參數列表中通過@Param定義參數名稱,在Sql語句中通過注解中所定義的參數名稱指定參數位置。此方式參數比較直觀的,推薦使用。
-
持久層接口方法
List<User> findPage1(@Param("startIndex") int startIndex, @Param("pageSize")int pageSize); -
映射文件
<select id="findPage1" resultType="com.mybatis.mapper.User"> select * from user limit #{startIndex},#{pageSize} </select> -
測試類
@Test public void testFindPage1(){ List<User> users = userMapper.findPage1(3,3); users.forEach(System.out::println); }
POJO傳參
自定義POJO類,該類的屬性就是要傳遞的參數,在SQL語句中綁定參數時使用POJO的屬性名作為參數名即可。此方式推薦使用。
-
自定義POJO
public class PageQuery { private int startIndex; private int pageSize; // 省略getter/setter/構造方法 } -
持久層接口方法
List<User> findPage2(PageQuery pageQuery); -
映射文件
<select id="findPage2" resultType="com.mybatis.pojo.User" parameterType="com.mybatis.pojo.PageQuery"> select * from user limit #{startIndex},#{pageSize} </select> -
測試類
@Test public void testFindPage2(){ PageQuery pageQuery = new PageQuery(3, 3); List<User> users = userMapper.findPage2(pageQuery); users.forEach(System.out::println); }
Map傳參
如果不想自定義POJO,可以使用Map作為傳遞參數的載體,在SQL語句中綁定參數時使用Map的Key作為參數名即可。此方法推薦使用。
-
持久層接口方法
List<User> findPage3(Map<String,Object> params); -
映射文件
<select id="findPage3" resultType="com.mybatis.pojo.User" parameterType="map"> select * from user limit #{startIndex},#{pageSize} </select> -
測試類
@Test public void testFindPage3(){ Map<String,Object> params = new HashMap(); params.put("startIndex",0); params.put("pageSize",4); List<User> users = userMapper.findPage3(params); users.forEach(System.out::println); }
MyBatis聚合查詢、主鍵回填
查詢用戶總數
-
持久層接口方法
int findCount(); -
映射文件
<select id="findCount" resultType="int"> select count(id) from user </select> -
測試類
@Test public void testFindCount(){ System.out.println(userMapper.findCount()); }
主鍵回填
有時我們需要獲取新插入數據的主鍵值。如果數據庫中主鍵是自增的,這時我們就需要使用MyBatis的主鍵回填功能。
-
持久層接口方法
void add(User user); -
映射文件
<insert id="add" parameterType="com.mybatis.user.User"> <!-- keyProperty:主鍵屬性名,keyColumn:主鍵列名,resultType:主鍵類型,order:執行時機 --> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID(); </selectKey> insert into user(username,sex,address) values(#{username},#{sex},#{address}) </insert>SELECT LAST_INSERT_ID():查詢剛剛插入的記錄的主鍵值,只適用于自增主鍵,且必須和insert語句一起執行。
-
測試類
@Test public void testAdd(){ User user = new User("×××", "男", "北京"); userMapper.add(user); session.commit(); System.out.println(user.getId()); }
MyBatis配置文件

< properties>標簽
MyBatis配置文件結構:
-configuration
-properties(屬性)
-property
-settings(全局配置參數)
-setting
-plugins(插件)
-plugin
-typeAliases(別名)
-typeAliase
-package
-environments(環境)
-environment
-transactionManager(事務管理)
-dataSource(數據源)
-mappers(映射器)
-mapper
-package
properties
屬性值定義。properties標簽中可以定義屬性值,也可以引入外部配置文件。無論是內部定義還是外部引入,都可以使用 ${name} 獲取值。
例如:我們可以將數據源配置寫到外部的db.properties中,再使用properties標簽引入外部配置文件,這樣可以做到動態配置數據源。
-
編寫db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=root -
在配置文件中引入db.properties
<properties resource="db.properties"></properties> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments>
當然我們也可以將數據源數據通過<properties>配置到MyBatis配置文件內,但這樣做沒什么意義。
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis"></property>
<property name="jdbc.username" value="root"></property>
<property name="jdbc.password" value="root"></property>
</properties>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
< settings>標簽
<settings>是配置MyBatis運行時的一些行為的,例如緩存、延遲加載、命名規則等一系列控制性參數。后期我們會使用該標簽配置緩存和延遲加載等。
< plugins>標簽
<plugins>是配置MyBatis插件的。插件可以增強MyBatis功能,比如進行sql增強,打印日志,異常處理等。后期我們會使用該標簽配置分頁插件。
< typeAliases>標簽
MyBatis對常用類有默認別名支持,比如java.lang.Stirng的別名為string。除此之外,我們也可以使用<typeAliases>設置自定義別名。
為一個類配置別名
<typeAliases>
<typeAlias type="全類名" alias="別名"></typeAlias>
</typeAliases>
此時我們即可在映射文件中使用自定義別名,如:
-
配置文件:
<typeAliases> <typeAlias type="com.mybatis.pojo.User" alias="User"> </typeAlias> </typeAliases> -
映射文件:
<select id="findAll" resultType="User"> select * from user </select>
為一個所有包下的所有類配置別名
<typeAliases>
<package name="包名"></package>
</typeAliases>
此時該包下的所有類都有了別名,別名省略包名,和類名相同。如:
-
配置文件:
<typeAliases> <package name="com.mybatis.pojo"></package> </typeAliases> -
映射文件:
<select id="findPage2" resultType="User" parameterType="PageQuery"> select * from user limit #{startIndex},#{pageSize} </select>
< environments>標簽
<environments>可以為MyBatis配置數據環境。
事務管理
<environments default="mysql">
<environment id="mysql">
<!-- JDBC:使用JDBC的提交和回滾 MANAGED:不做事務處理-->
<transactionManager type="JDBC"></transactionManager>
</environment>
</environments>
連接池
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<!-- 連接池設置 -->
<dataSource type="POOLED">
<!-- 數據源設置... -->
</dataSource>
</environment>
</environments>
dataSource的type屬性:
- POOLED:使用連接池管理連接,使用MyBatis自帶的連接池。
- UNPOOLED:不使用連接池,直接由JDBC連接。
- JNDI:由JAVAEE服務器管理連接,如果使用Tomcat作為服務器則使用Tomcat自帶的連接池管理。
< mappers>標簽
<mappers>用于注冊映射文件或持久層接口,只有注冊的映射文件才能使用,共有四種方式都可以完成注冊:
-
使用相對路徑注冊映射文件
<mappers> <mapper resource="com/mybatis/mapper/UserMapper.xml"/> </mappers> -
使用絕對路徑注冊映射文件
<mappers> <mapper url="file:///C:\Users\a\IdeaProjects\mybatiscase\mybatisDemo1\src\main\resources\com\mybatis\mapper\UserMapper.xml"/> </mappers> -
注冊持久層接口
<mappers> <mapper class="com.mybatis.mapper.UserMapper"/> </mappers> -
注冊一個包下的所有持久層接口
<mappers> <package name="com.mybatis.mapper"/> </mappers>
浙公網安備 33010602011771號