一、ORM
ORM(Object Relational Mapping),對象關係映射,emmm...這裏把它分成三個詞語組合去理解的話
對象:POJO(普通的java對象)
關係:二維表,數據庫中的表
映射:對象中的屬性,與表中的字段,存在對應關係
這麼說吧,使用ORM技術,在程序中可以通過對象,進行數據操作
如何實現?
JPA( Java Persistence API),“JPA通過 註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中。”具體請訪問:https://blog.csdn.net/alik20/article/details/53131741
二、ORM框架(Hibernate、Mybatis)
1、Hibernate
全自動orm框架,對JDBC訪問數據庫代碼做了封裝,簡化dao層編碼工作,可自動生成SQL語句,自動執行,以面向對象的方式操作數據,例如:session.save(User)、session.update(User)、session.delete(User)......
特點:數據持久化
hibernate在進行對象操作比如:save()或update()時,並沒有直接將數據寫入數據庫中,而是先緩存到session中,然後調用flush()將緩存中數據提交到數據庫
注: flush時,按照insert,update,……,delete的順序提交所有登記的操作
映射關係:一對一、一對多、多對多
2、Mybatis
半自動化orm框架,手工匹配提供的POJO,SQL語句和映射關係(Hibernate只需提供POJO和映射關係即可)
(1)基本構成:
SqlSessionFactoryBuilder(構造器),根據配置信息或代碼來生成SqlSessionFactory(工廠接口);
SqlSessionFactory:來生成SqlSession
SqlSession:執行SQL並返回結果
SQLMapper:由一個Java類和XML(或註解)構成
@Test
public void testQueryById() throws IOException{
//構造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//讀取配置文件
String resource = "mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resource);
//獲得工廠
SqlSessionFactory factory = builder.build(in);
//獲得session
SqlSession session = factory.openSession();
//獲取映射器,映射器通過命名空間和方法名稱找到對應的SQL,執行SQL並返回結果
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryById(1);
System.out.println(user);
//註解實現
UserMapper2 mapper2 = session.getMapper(UserMapper2.class);
User user2 = mapper2.queryById(2);
System.out.println(user2);
}
SqlSession兩個作用
a. 獲取映射器,讓映射器通過命名空間和方法名稱找到對應的SQL,執行SQL並返回結果
b. 直接通過命名信息去執行SQL返回結果
(2)映射器
映射器是由自定義java接口和XML文件(或註解)共同組成的。
舉個栗子(=.=)
//接口類
public interface UserMapper {
public User queryById(Integer id);
}
映射文件(*mapper.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口 -->
<mapper namespace="com.lz.mapper.UserMapper">
<!--resultType:返回類型 com.lz.entity.User,也可以用別名,
前提是要在mybatis-config.xml中配置parameterType:參數類型-->
<select id="queryById" resultType="user" parameterType="int">
select * from user where id = #{id}
</select>
</mapper>
註解實現的映射器
public interface UserMapper {
@Select("select * from user where id = #{id}")
public User queryById(Integer id);
}
(3)傳參方式
a.同個類裏面的屬性,就是bean的方式傳遞
b.不是的話,map和註解選擇
c.少的(小於5個),就選註解,多的話就選map
舉個栗子(=.=)
public interface UserMapper {
//普通傳參
public User queryById(Integer id);
//map
public User getMap(Map<String,Object> map);
//兩個參數以上使用註解區分,註解參數與方法參數不一致時,以註解參數爲主
public User getUser(@Param("param1")String name,@Param("param2")Integer age);
}
<?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.lz.mapper.UserMapper">
<!--
resultType:返回類型 com.lz.entity.User,
也可以用別名,前提是要在mybatis-config.xml中配置
parameterType:參數類型
-->
<select id="queryById" resultType="user" parameterType="int">
select * from user where id = #{id}
</select>
<select id="getMap" resultType="user" parameterType="map">
select id,name,age from user where name = #{name} and age = #{age}
</select>
<select id="getUser" resultType="user">
select id,name,age from user where name = #{param1} and age = #{param2}
</select>
</mapper>
(4)“#”與“$”
#:將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:where id = #{id},如果傳入的值是123,那麼解析成sql時的值爲where id = “123”,如果傳入的值是id,則解析成的sql爲where id = “id”。
$:將傳入的數據直接顯示生成在sql中。如:where id = ${id},如果傳入的值是123,那麼解析成sql時的值爲where id = 123, 如果傳入的值是id,則解析成的sql爲where id = id。
# 防止sql注入,而 $ 不能;
$ 一般用於動態傳參,例如表名:select ${columns} from table
(5)動態SQL
<if>判斷條件</if>
<where>自動添加where關鍵字,去掉多餘的and關鍵字</where>
<trim>多出的and會去掉</trim>
<set>用於更新操作;會去掉多餘的逗號</set>
舉個栗子(=.=)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace指的就是接口的全類名 -->
<mapper namespace="com.lz.dao.IUserDao">
<!-- type這裏用了別名(com.lz.entity.User) -->
<resultMap type="user" id="userMap">
<!-- 設置映射關係 -->
<result column="is_admin" property="isAdmin" />
</resultMap>
<!-- 抽取共用的sql語句 -->
<sql id="base_user">
id,
NAME,
password,
is_admin
</sql>
<select id="queryById" resultType="user" resultMap="userMap">
SELECT<include refid="base_user" />FROMt_userWHEREid = #{id}
</select>
<!-- if -->
<select id="queryUser" resultMap="userMap">
SELECT<include refid="base_user" />
FROMt_userWHERE 1 = 1
<!-- 字符串判斷非空的時候有兩種情況 concat 鏈接字符串 -->
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like concat("%",#{name})
</if>
</select>
<!-- where -->
<select id="queryUser" resultMap="userMap">
select<include refid="base_user"/>
fromt_user
<!-- where標籤自動添加where關鍵字,去掉多餘的and關鍵字 -->
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like concat("%",#{name})
</if>
</where>
</select>
<!-- trim -->
<select id="queryUser" resultMap="userMap">
select<include refid="base_user"/>
fromt_user
<!-- 去掉多餘的內容
prefix:在trim標籤內sql語句加上前綴
suffix:在trim標籤內sql語句加上後綴
prefixOverrides:指定去除多餘的前綴內容
suffixOverrides:指定去除多餘的後綴內容,
如: suffixOverrides=",",去除trim標籤內sql語句多餘的後綴"," 號-->
<trim prefix="where" prefixOverrides="and" >
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like concat("%",#{name})
</if>
</trim>
</select>
<!-- set -->
<update id="update" parameterType="user">
UPDATE t_user
<set>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="password != null and password != ''">
password = #{password}
</if>
</set>
WHEREid = #{id}
</update>
</mapper>
(6)映射關係
resultMap設置映射關係
column的屬性要與sql語句中的字段保持一致
對一
association
property:多的一方中保存一的方的屬性名稱
javaType:一的一方的類型
對多
collection
property:一的一方中保存多一方的集合名稱
ofType:多的一方的類型
舉個栗子(=.=),一個人擁有多個地址
<resultMap type="user" id="userMap">
<id column="uid" property="id" />
<result column="u_name" property="uName" />
<!-- 對多 -->
<collection property="addresses" ofType="address">
<!-- 地址表 -->
<id column="aid" property="id" />
<result column="a_name" property="aName" />
</collection>
</resultMap>
對一關係配置也類似,更多詳細內容略。啊哈~還有很多知識點,一口吞不了象,來日方長......