一、ORM
ORM(Object Relational Mapping),对象关系映射,emmm...这里把它分成三个词语组合去理解的话
对象:POJO(普通的java对象)
关系:二维表,数据库中的表
映射:对象中的属性,与表中的字段,存在对应关系
这么说吧,使用ORM技术,在程序中可以通过对象,进行数据操作
如何实现?
JPA( Java Persistence API),“JPA通过 注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。”具体请访问:https://blog.youkuaiyun.com/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>
对一关系配置也类似,更多详细内容略。啊哈~还有很多知识点,一口吞不了象,来日方长......