Spring Ioc源碼分析系列--Ioc容器BeanFactoryPostProcessor後置處理器分析 前言 上一篇文章Spring Ioc源碼分析系列--Ioc源碼入口分析已經介紹到Ioc容器的入口refresh()方法,並且分析了refresh()方法裡面的前三個子方法分析了一下。還記得分 ...
Mybatis快速入門
Mybatis開發步驟
- 添加依賴坐標
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
- 編寫POJO映射文件,如UserMapper.xml 可放在resource資源目錄下,註意.和/的區別
<?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="userMapper">
<select id="findAll" resultType="com.rsk.entity.User">
select * from user
</select>
</mapper>
- 編寫mybatis配置文件,mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--數據源環境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test_db?serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!--載入映射文件-->
<mappers>
<mapper resource="com/rsk/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
- 編寫測試類
public class Test1 {
@Test
public void test1() throws IOException {
//獲得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
//獲得sqlSession工廠
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//執行操作
List<User> users = sqlSession.selectList("userMapper.findAll");
System.out.println(users);
//釋放資源
sqlSession.close();
}
}
Mybatis傳統增刪改查方式
mapper.xml
<mapper namespace="userMapper">
<!--查詢操作-->
<select id="findAll" resultType="com.rsk.entity.User">
select * from user
</select>
<!--插入操作-->
<insert id="addUser" parameterType="com.rsk.entity.User">
insert into user values(#{id},#{name},#{pwd})
</insert>
<!--更新操作-->
<update id="update" parameterType="com.rsk.entity.User">
update user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
<!--刪除操作-->
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
</mapper>
Test.java
//獲得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
//獲得sqlSession工廠
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//查詢操作
//List<User> users = sqlSession.selectList("userMapper.findAll");
//插入操作
//int insert = sqlSession.insert("userMapper.addUser", user);
//更新操作
//sqlSession.update("userMapper.update", user);
//刪除操作
sqlSession.delete("userMapper.delete", 26);
sqlSession.commit();
//釋放資源
sqlSession.close();
Mybatis核心標簽
- properties:載入外部的properties文件
<!--通過標簽載入外部properties文件-->
<properties resource="jdbc.properties"></properties>
- typeAliases:設置類型別名,該標簽必須在environments標簽上面
<!--別名設置-->
<typeAliases>
<typeAlias type="com.rsk.entity.User" alias="user"></typeAlias>
</typeAliases>
- mappers:載入映射配置
<!--載入映射文件-->
<mappers>
<mapper resource="com/rsk/mapper/UserMapper.xml"></mapper>
</mappers>
- enviroments:資料庫環境配置標簽
<!--數據源環境-->
<environments default="development">
<environment id="development">
<!--指定事務管理類型,為JDBC(依賴數據源獲得連接來管理事務)或者MANAGED(讓容器管理事務,預設情況下會關閉連接)-->
<transactionManager type="JDBC"></transactionManager>
<!--指定數據源類型,UNPOOLED(數據源每次被請求時候打開或者關閉連接,POOLED(利用連接池將JDBC對象組織起來),JNDI(用於EJB或者應用伺服器容器使用))-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}?serverTimezone=GMT%2B8"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
Mybatis代理實現DAO層
採用Mybatis的代理開發實現DAO層,我們只需要編寫Mapper介面(相當於DAO介面),然後由Mybatis框架根據介面定義創建介面的動態代理對象,該動態代理對象的方法體相當於是DAO層的實現類方法。遵循以下規範:
- Mapper.xml中的namespace與mapper介面的全限定名稱相同
- Mapper.xml中的每個statement的id和Mapper介面方法名相同
- Mapper.xml中的每個sql的parameterType與和Mapper介面方法的輸入參數類型相同
- Mapper.xml中的每個sql的resultType與和Mapper介面方法的返回參數類型相同
- 編寫DAO介面UserMapper.class
public interface UserMapper {
public List<User> findAll() throws IOException;
public User findById(int id);
}
- 編寫映射文件UserMapper.xml,namespace需要指定到DAO介面的位置
<?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="com.rsk.dao.UserMapper">
<!--查詢操作-->
<select id="findAll" resultType="user">
select * from user
</select>
<select id="findById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
<!--插入操作-->
<insert id="addUser" parameterType="com.rsk.entity.User">
insert into user values(#{id},#{name},#{pwd})
</insert>
<!--更新操作-->
<update id="update" parameterType="com.rsk.entity.User">
update user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
<!--刪除操作-->
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
</mapper>
- Service調用sqlSession的getMapper方法
public class ServiceDemo {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> all = userMapper.findAll();
User user = userMapper.findById(1);
System.out.println(all);
System.out.println(user.getName());
}
}
動態sql
面對複雜的業務邏輯,SQL需要進行動態調整,如果對每個不同條件專門寫一條sql則需要寫多個介面中的方法,因此可以選擇動態生成SQL語句,從而減少代碼量
<where><if></if></where>
標簽:條件判斷後拼接
<!--動態SQL查詢-->
<select id="findByCondition" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="pwd!=null">
and pwd=#{pwd}
</if>
</where>
</select>
對應的介面中的方法:
//條件查詢
public List<User> findByCondition(User user);
測試環境中的代碼:
@Test
public void test2(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//條件對象
User user = new User();
user.setId(1);
List<User> all = mapper.findByCondition(user);
System.out.println(all);
}
<foreach>
標簽:迴圈拼接
<!--動態SQL查詢-->
<select id="findByIds" parameterType="list" resultType="user">
select * from user
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
對應介面中的方法:
public List<User> findByIds(List<Integer> ids);
對應測試代碼:
@Test
public void tests(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//條件對象
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
List<User> all = mapper.findByIds(ids);
System.out.println(all);
}
sql語句抽取
將動態SQL共用的sql語句代碼段進行提取,避免修改表名時修改全部的sql,達到sql片段重用的目的
<!--sql語句片段抽取-->
<sql id="selectUser">select * from user</sql>
/*sql語句片段引入*/
<include refid="selectUser"></include>
一對一查詢
主要難點在於查詢出來的數據包含兩個實體類的屬性,需要利用resultMap標簽進行配置,course類實體需要擁有user成員對象
CourseMapper.xml
<resultMap id="courseMap" type="com.rsk.entity.Course">
<!--手動指定欄位與實體屬性間的映射關係-->
<id column="cid" property="id"></id>
<result column="cno" property="cno"></result>
<result column="cname" property="cname"></result>
<!--配置外鍵所在表的映射關係-->
<association property="user" javaType="com.rsk.entity.User">
<id column="uid" property="id"></id>
<result column="name" property="name"/>
<result column="pwd" property="pwd"/>
</association>
</resultMap>
<select id="findAll" resultMap="courseMap">
select *, c.id cid
from course c, user u where c.uid=u.id
</select>
test
@Test
public void test5(){
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
List<Course> all = mapper.findAll();
System.out.println(all);
}