MyBatis笔记

一、什么是Mybatis:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jlXMVsUR-1602116932300)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200920091057291.png)]

​ 这里借用官网的一句话介绍什么是mybatis:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

二、Mybatis相对JDBC有哪些优势

首先我们来看一看jdbc连接数据库的连接方法:


public static void main(String[] args) {
			Connection connection = null;
			PreparedStatement preparedStatement = null;
			ResultSet resultSet = null;
			
			try {
				//1、加载数据库驱动
				Class.forName("com.mysql.jdbc.Driver");
				//2、通过驱动管理类获取数据库链接
				connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis", "root", "root");
				//3、定义sql语句 ?表示占位符
			        String sql = "select * from user where username = ?";
				//4、获取预处理statement
				preparedStatement = connection.prepareStatement(sql);
				//5、设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
				preparedStatement.setString(1, "王五");
				//6、向数据库发出sql执行查询,查询出结果集
				resultSet =  preparedStatement.executeQuery();
				//7、遍历查询结果集
				while(resultSet.next()){
					User user 
					System.out.println(resultSet.getString("id")+"  "+resultSet.getString("username"));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				//8、释放资源
				if(resultSet!=null){
					try {
						resultSet.close();//释放结果集
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(preparedStatement!=null){
					try {
						preparedStatement.close();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(connection!=null){
					try {
						connection.close();//关闭数据库连接
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
 
			}
 
		}

通过上面的一段jdbc连接数据代码,我们看有哪些不好的地方:

1.在创建connection的时候,存在硬编码问题(也就是直接把连接信息写死,不方便后期维护)

2.preparedStatement对象在执行sql语句的时候存在硬编码问题。

3.每次在进行一次数据库连接后都会关闭数据库连接,频繁的开启/关闭数据连接影响性能。

简单的说一下mybatis相对jdbc的优势:

1.mybatis是把连接数据库的信息都是写在配置文件中,因此不存在硬编码问题,方便后期维护。

2.mybatis执行的sql语句都是通过配置文件进行配置,不需要写在java代码中。

3.mybatis的连接池管理、缓存管理等让连接数据库和查询数据效率更高。

三、Mybatis框架的原理介绍

这里就通过一张图来对mybatis框架原理进行介绍吧:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hoXpteM1-1602116932304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200916082215249.png)]

四、Mybatis sqlsession的获取:

在测试类定义一个获取 getSqlSession的方法:

public SqlSession getSqlSession() {
		String resource = "mybatis-config.xml";
		SqlSession sqlSession = null;
		// 1 获取mybatis-config.xml的输入流
		InputStream is = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 2 创建SqlSessionFactory对象,完成对配置文件的读取
			SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
			// 3 创建sqlSession
			sqlSession = factory.openSession();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sqlSession;
	}

通过sqlSession对象获取对应的Mapper接口

SqlSession sqlSession = getSqlSession();
UserMapper udao = sqlSession.getMapper(UserMapper.class);
User user = udao.getUserById(1);//

五、Mybatis全局配置文件

SqlMapConfig.xml是Mybatis的全局配置文件,它的名称可以是任意,但是一般命名都为(SqlMapConfig)

4.1.全局配置文件的类容和顺序

Properties(属性)

Settings(全局参数设置)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境信息集合)

environment(单个环境信息)

transactionManager(事物)

dataSource(数据源)

mappers(映射器)

4.2.常见配置详解

properties标签:

Mybatis可以通过该标签来读取java配置信息:

例如在工程中对数据源信息写在db.properties文件中,可以通过properties标签来加载该文件。

db.properties:

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mybatis
db.username=root
db.password=root

SqlMapConfig.xml使用properties标签:

<!-- 通过properties标签,读取java配置文件的内容 -->
<properties resource="db.properties" />
 
<!-- 配置mybatis的环境信息 -->
<environments default="development">
	<environment id="development">
		<!-- 配置JDBC事务控制,由mybatis进行管理 -->
		<transactionManager type="JDBC"></transactionManager>
		<!-- 配置数据源,采用dbcp连接池 -->
		<dataSource type="POOLED">
			<property name="driver" value="${db.driver}"/>
			<property name="url" value="${db.url}"/>
			<property name="username" value="${db.username}"/>
			<property name="password" value="${db.password}"/>
		</dataSource>
	</environment>
    <!--value="com.mysql.cj.jdbc.Driver" -->
    <!-- value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT&amp;nullCatalogMeansCurrent = true"-->

1、 先加载properties中property标签声明的属性

1、 先加载properties中property标签声明的属性

因此在property中的name属性的值和value比properties中的resource属性先加载。后加载的db.properties会覆盖于property加载属性和值。

<property name="db.username",value="root"/>

2、 再加载properties标签引入的java配置文件中的属性

3、 parameterType的值会和properties的属性值发生冲突。因此,在properties文件里的内容命名最好加上db.代表是跟数据源相关的属性,这样就不容易跟以后的属性发生冲突。

settings标签:

该标签时mybatis的全局设置,该设置会影响mybatis的运行。

一般我们使用使用该标签来开启二级缓存和懒加载。

以下是几张settings配置项的说明:

img

img

typeAliases标签

该标签是对po类进行别名设置,这样,在后面使用po类的时候就可以直接通过别名引用,而不需要通过po类的全限定名来引用。这样可以提高我们的开发效率。

首先介绍下Mybatis的默认提供的别名有:

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal

自定义单个别名:这种方式只能定义单个类的别名。

下面的代码就是把com.lc.mybatis.po.User类定义为user的别名

<typeAliases>



		<!-- 设置单个别名 -->



		<typeAlias type="com.lc.mybatis.po.User" alias="user"/>



	</typeAliases>

自定义之批量定义别名:

下面代码是把com.lc.mybatis.po类下的所有类都声明别名,默认的别名就是类名(类名大小写都可以)

<!-- 设置别名 -->
	<typeAliases>

		<!-- 批量设置别名 -->

		<!-- package:指定包名称来为该包下的po类声明别名,默认的别名就是类名(类名首字母大小写都可以) -->

		<package name="com.lc.mybatis.po"/>

	</typeAliases>

六、databaseIdProvider环境

MyBatis 可以根据不同的数据库厂商执行不同的语句。

1.1在mybatis-config.xml配置:

<environments default="dev_oracle">
		<environment id="dev_mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${user}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
		<environment id="dev_oracle">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${orcl.driver}" />
				<property name="url" value="${orcl.url}" />
				<property name="username" value="${orcl.username}" />
				<property name="password" value="${orcl.password}" />
			</dataSource>
		</environment>
	</environments>
	<databaseIdProvider type="DB_VENDOR">
	<!-- 为不同的数据库厂商起别名 -->
	<property name="MySQL" value="mysql" />
	<property name="Oracle" value="oracle" />
	</databaseIdProvider>

1.2在EmployeeMapper.xml中配置:

<select id="getEmpById" resultType="com.mybatis.bean.Employee">
		select * from tbl_employee where id = #{id}
	</select>
	<select id=" getEmpById" resultType="com.mybatis.bean.Employee" databaseId="mysql">
		select * from tbl_employee where id = #{id}
	</select>
	<select id="getEmpById" resultType="com.mybatis.bean.Employee"
		databaseId="oracle">
		select * from employee where id=#{id}
	</select>

1.3在db.properties配置:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
user=root
password=root

orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:orcl
orcl.username=qq
orcl.password=root
mappers标签

该标签的作用是加载映射文件

方式一:

该方式是加载相对于类路径下的映射文件:


<mappers>
   <mapper resource="com/mybatis/dao/EmployeeMapper.xml"/>
</mappers>

方式二:

该方式使用全限定路径

<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />

方式三:

该方式使用mapper接口的全限定类名

<mapper class="cn.itcast.lc.mapper.UserMapper"/>

此方式要求:

Mapper接口Mapper映射文件名称相同且在同一个目录下。

方式四:

该方式是加载指定包下的所有映射文件

<package name="cn.lc.mybatis.mapper"/>

此方式要求:

Mapper接口Mapper映射文件名称相同且在同一个目录下。

七、映射文件

1.1映射文件insert

​ 获取oracle序列封装到javaBean

<!-- 
	获取非自增主键的值:
		Oracle不支持自增;Oracle使用序列来模拟自增;
		每次插入的数据的主键是从序列中拿到的值;如何获取到这个值;
	 -->
	<insert id="addEmp" databaseId="oracle">
		<!-- 
		keyProperty:查出的主键值封装给javaBean的哪个属性
		order="BEFORE":当前sql在插入sql之前运行
			   AFTER:当前sql在插入sql之后运行
		resultType:查出的数据的返回值类型
		
		BEFORE运行顺序:
			先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
			在运行插入的sql;就可以取出id属性对应的值
		AFTER运行顺序:
			先运行插入的sql(从序列中取出新值作为id);
			再运行selectKey查询id的sql;
		 -->
		<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
			<!-- 编写查询主键的sql语句 -->
			<!-- BEFORE-->
			select EMPLOYEES_SEQ.nextval from dual 
			<!-- AFTER:
			 select EMPLOYEES_SEQ.currval from dual -->
		</selectKey>
		
		<!-- 插入时的主键是从序列中拿到的 -->
		<!-- BEFORE:-->
		insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL) 
		values(#{id},#{lastName},#{email<!-- ,jdbcType=NULL -->}) 
		<!-- AFTER:
		insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL) 
		values(employees_seq.nextval,#{lastName},#{email}) -->
	</insert>
⭐️参数(Parameters)传递:

·单个参数
-可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数﹐不需要经过任何处理。
⭐️·多个参数
-任意多个参数,都会被MyBatis重新包装成一个Map传入。Map的key是param1 , param2 ,O,1…,值就是参数的值。
·命名参数―——为参数使用@Param起一个名字,MyBatis就会将这些参数封
装进map中,key就是我们自己指定的名字

接口使用@Param来传递多个参数:

public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);

xml配置:

<!--  public Employee getEmpByIdAndLastName(Integer id,String lastName);-->
 	<select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee">
 		select * from tbl_employee where id = #{id} and last_name=#{lastName}
 	</select>
map集合类型:

在test测试类封装map

Map<String,Object> map=new HashMap<String,Object>();
					map.put("id", 2);
					map.put("lastname", "zhangsan");
					Employee employee=mapper.getEmployeeByMap(map);

mapper接口:

//map集合类型
	public Employee getEmployeeByMap(Map<String,Object> map);

mapper.xml“:

<select id="getEmployeeByMap" resultType="com.mybatis.bean.Employee"
		databaseId="mysql">
		select * from tbl_employee where id=#{id} and lastname=#{lastname}
	</select>

八,关联关系

1.多对一:

(多个员工对应一个角色),在user表放一个角色表的对象

public class User {
	private Integer id; // id
	private String user_Code; // 用户编码
	private String user_Name; // 用户名称
	private String user_Password; // 用户密码
	private Integer gender; // 性别
	private Date birthday; // 出生日期
	private String phone; // 电话
	private String address; // 地址
	private Integer userRole; // 用户角色
	private String rolename;
	private Integer created_By; // 创建者
	private Date creation_Date; // 创建时间
	private Integer modify_By; // 更新者
	private Date modify_Date; // 更新时间
	
	private Role role;// 角色对象

在UserMapper.xml文件中配置多对一的映射关系:

标签用:

<resultMap id="userlist2" type="cn.pojo.User">
		<id property="id" column="id"></id>
		<result property="user_Code" column="userCode" />
		<result property="user_Name" column="userName" />
		<result property="user_Password" column="userPassword" />
		<result property="gender" column="gender" />
		<result property="birthday" column="birthday" />
		<result property="phone" column="phone" />
		<result property="address" column="address" />
		<result property="created_By" column="createdBy" />
		<result property="creation_Date" column="creationDate" />
		<result property="modify_By" column="modifyBy" />
		<result property="modify_Date" column="modifyDate" />
		<association property="role" javaType="cn.pojo.Role" resultMap="rolelist">
    		
		</association>
	</resultMap>
	<resultMap id="rolelist" type="cn.pojo.Role">
		<id property="id" column="id" />
		<result property="roleCode" column="roleCode" />
		<result property="roleName" column="roleName" />
	</resultMap>

2.一对多:

(一个角色对应多名员工)在role表中放一个user的集合:

public class Role {
	
	private int id;

	private String roleCode;

	private String roleName;
	
	private List<User> userlist;

在RoleMapper.xml文件中配置一对多的映射关系:

标签用:

<resultMap id="rolelist2" type="cn.pojo.Role">
		<id property="id" column="id" />
		<result property="roleCode" column="roleCode" />
		<result property="roleName" column="roleName" />
		<collection property="userlist" ofType="cn.pojo.User" resultMap="userlist">
    
		</collection>
	</resultMap>
	<resultMap id="userlist" type="cn.pojo.User">
		<id property="id" column="id" />
		<result property="user_Code" column="userCode" />
		<result property="user_Name" column="userName" />
		<result property="user_Password" column="userPassword" />
		<result property="gender" column="gender" />
		<result property="birthday" column="birthday" />
		<result property="phone" column="phone" />
		<result property="address" column="address" />
		<result property="userRole" column="userRole" />
		<result property="created_By" column="createdBy" />
		<result property="creation_Date" column="creationDate" />
		<result property="modify_By" column="modifyBy" />
		<result property="modify_Date" column="modifyDate" />
	</resultMap>
```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值