Mybatis

Mybatis

mybatis是一个半自动的ORM映射框架(支持一对一,一对多的实现,多对多采用两个一对多进行实现

1.mybatis的优势

  1. 比起jdbc的操作,减少了一些重复的代码量工作,也方便能够集成到后期的管理框架中

  2. mybatis提供在XML中编写sql语句,不直接入侵在代码中(方便分类修改)

  3. 分别提供的xml标签和mapper标签(xml标签可实现动态SQL语句,也就是嵌入条件判断和循环,比较类似存储函数),mapper标签支持对象正确的解析至数据库中

2.mybatis框架执行原理

1.sqlConfigXMl配置文件(一个全局的配置文件)(可配置映射文件和连接数据源和事务等)

2.通过配置文件构建出可构建操作数据会话的会话工厂,也就是我们常说的sqlSessionFactory(涉及工厂模式代码设计)

3.通过sqlSessionFactory生产出相互独立的sqlsession,为什么是独立的会话,既然是独立的会话,那也有全局的会话进行数据库层面上面的操作

4.sqlsession之所以能够操作,依赖一个叫Executor的执行器,通过该执行器进行数据库的CRUD操作

5.Executor的执行器需要操作CRUD的动作由谁而来,就是由mapperstatement对象读取mapper映射文件

3.mybatis使用流程

  1. src目录下构建mybatis的全局配置文件mybatisCfg.xml,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 数据库连接环境配置 -->
	<environments default="development">
		<!-- 标明mybaitis环境 id唯一 -->
		<environment id="development">
			<!-- JDBC – 这个配置直接简单使用了 JDBC 的提交和回滚设置。 它依赖于从数据源得 到的连接来管理事务范围。JDBC默认是自动提交 -->
			<transactionManager type="JDBC" />
			<!-- 采用数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<!-- 避免环境的不统一,造成数据操作乱码 -->
				<property name="url"
					value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	<!-- 添加需要被映射的文件 -->
	<mappers>
		<mapper resource="com/wcy/dao/PersonMapper.xml" />
	</mappers>
</configuration>

2.mapper映射文件格式: 

<?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.wwj.dao.PersonDao">
	<insert id="savePerson" parameterType="com.wcy.model.Person">
		insert into
		person(name,address,bir) values(#{name},#{address},#{bir});
	</insert>

	<update id="updatePerson" parameterType="com.wcy.model.Person">
		update person set
		name=#{p.name},address=#{address},bir=#{bir}
		where id=#{id}
	</update>

	<delete id="deletePersonById" parameterType="int">
		delete from person
		where id=#{id}
	</delete>


	<select id="getPersonInfos" resultType="com.wcy.model.Person">
		select * from person
	</select>

</mapper>

3.映射文件中属性

1.namespace:对应dao层接口全类名

2.id:和接口中方法一致

3.定义sql语句标签:

  • <insert>

  • <insert>

  • <delete>

  • <update>

4.有返回值要接收时

  • resultType:接收基本数据,复杂类型,(全类名)

  • resultmap:自定义类型接收,需要创建对应的实体类

5.parameterType:输入类型(可不写)

#{}:接收参数,在接口方法中获取参数

6.接收方式

  • 索引接收

  List<Person>  getPersonInfosByNameAndID(String name ,int id);
  	<select id="getPersonInfosByNameAndID" >
  		select * from person where name = #{0} and id = #{1} 
  	</select>
  • map接收

   /**
     *  根据map进行查询
     * @param attrs
     * key1 id  key2 name
     * @return
     */
    List<Person>  getPersonInfosByMap(Map attrs);
    //------------------动作实现
  <select id="getPersonInfosByMap"  parameterType="java.util.Map" resultType="com.wwj.model.Person">
		select * from person where id =
		#{id} and name = #{name}
	</select>
	  //----------------调用测试
	  Map<String,Object>  attrs = new HashMap<>();
		attrs.put("id", 2);
		attrs.put("name", "小王");
		session.selectList("getPersonInfosByMap", attrs);
  • 注解接收

    /**
     * 根据用户唯一id查询信息
     * @param id
     * @return
     */
    Person  getPersonInfo(@Param("pid") int id);
    //---------------动作实现
	<select id="getPersonInfo" 
		resultType="com.wwj.model.Person">
		select * from person where id =
		#{pid}
	</select>
	//---------调用测试
	session.selectOne("getPersonInfo", 2);

 

  • 自定义结果类型接收(resultmap)

//----- 实体类
public class Card {
		private String cname;
		}
public class Person implements Serializable {
	private  Integer   id;
	private  String name;
	private  Date bir;
	private  String address;
	private  List<Card>  cards;
	}
//----构建自定义的resultmap封装 注意   collection(集合)association(联系)
	<resultMap type="com.wcy.model.Person" id="personRS">
		<!--column指向数据库列名 property指向pojo对象中字段名 -->
		<result column="name" property="name" />
		<!-- property指的是在bean中字段名 ofType类的全定向名 -->
		<collection property="cards" ofType="com.wwj.model.Card">
			<result column="cname" property="cname" />
		</collection>
	</resultMap>
//--------映射的动作实现
    <select id="getPersonsOfCard" resultMap="personRS">
        select
        person.name,card.cname
        from person
        INNER JOIN card
        on person.id = card.pid
    </select>
//--------代码操作
		List<Person> persons = session.selectList("getPersonsOfCard");
		for (Person person : persons) {
			System.out.println(person.getCards().get(0).getCname());
			System.out.println(person.getCards().get(1).getCname());
		}

自定义resultMap封装中的标签

<id/>:数据库中的主键

其中属性:

column:数据库列名

property:在bean中字段名

<result/>:数据库中其他的字段

<collection></collection>:一对多的时候使用,映射文件引入用:ofType类的全类名

<association></association>:多对一的时候使用,javaType:类的全类名

mybatis立即返回主键值

应用场景:当我们需要在当前事务插入数据后立即获取数据的主键id,做下一步额外操作,并且不因为并发高的情况下取错值而考虑

  <insert id="savePerson" parameterType="com.wcy.model.Person">
		<selectKey keyProperty="id" resultType="int" order="AFTER">
			select last_insert_id()
		</selectKey>
		insert into
		person(name,address,bir) values(#{name},#{address},#{bir});
	</insert>
	//------------------------------------------------------------
		// 操作数据
		Person p = new Person();
		p.setName("小小王");
		p.setBir(parse);
		int result = session.insert("savePerson", p);
		System.out.println(result);
		System.out.println(p.getId());
  • keyProperty=”返回主键的id的属性名”
  • resultType=”主键类型”
  • order=”“什么时候执行,在SQL执行前还是执行后执行,两个取值:BEFORE和AFTER
  • select last_insert_id()取到最后生成的主键,只在当前事务中取

调用

//读取配置文件

​ InputStream is = Resources.getResourceAsStream(“配置文件.xml”); ​

//产生sqlSessionFactory ​

SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is); ​

//产生sqlSession对象 ​

SqlSession session = build.openSession();

//获取映射(映射的dao层的.class文件)

TestUserDao mapper = session.getMapper(TestUserDao.class);

//调用方法

TestUser userUseWhere = mapper.getUserUseWhere(m);

session.commit();

session.close();

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值