快速学习MyBatis
MyBatis学习
- 简单介绍
- 入门程序
- 配置文件
- 映射文件
- 关系映射
- 一对一
- 一对多
- 多对多
浅入MyBatis
简单介绍
什么是 MyBatis?
MyBatis是一个数据持久层(ORM)框架。把实体类和SQL语句之间建立了映射关系,是一种半自动化的ORM实现。
MyBatis 的主要思想是将程序中的大量 SQL 语句抽取出来,配置在配置文件中,以实现 SQL 的灵活配置。
ORM又是什么?
ORM(Object/Relational Mapping):对象关系映射,它完成面向对象的编程语言到关系数据库的映射。它的作用是把持久化对象的保存、修改、删除等操作,转换成对数据库的操作。
ORM 基本映射关系:
- 数据表映射类
- 数据表的行映射对象(实例)
- 数据表的列(字段)映射对象的属性
MyBatis 的三层功能架构
- API接口层:提供给外部使用的接口 API,通过本地 API 来操纵数据库。接口层一但接收到调用请求就会调用数据处理层来完成具体的数据处理。
- 数据处理层:负责具体的 SQL 查找、SQL 解析、SQL 执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
- 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件,为上层的数据处理层提供最基础的支撑
MyBatis的优点
- 简单小巧灵活易于上手,方便浏览修改 SQL 语句
- 解除 SQL 与程序代码的耦合
- 提供对象关系映射标签,支持对象与数据库的 ORM 字段关系映射
- 提供 xml 标签,支持编写动态 SQL
MyBatis 与 JDBC 的区别
Mybatis 是基于 JDBC 的。Java 与数据库操作仅能通过 JDBC 完成。 Mybatis 也要通过 JDBC 完成数据查询、更新这些动作。Mybatis 仅仅是在 JDBC 基础上做了,OO 化、封装事务管理接口这些东西。
入门程序
数据库准备,新建名为mybatis的数据库,建数据库表
程序生成器(修改generatorConfig.xml→选择lib文件夹,Shift键加鼠标右键进入li目录下,执行脚本java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite)
generatorConfig.xml文件:
执行后生成的目录结果:
打开eclipse,新建名为Mybatis的项目,在src里新建三个包(如图所示),包名要和上图generatorConfig.xml文件的一样。
把生成的文件导入相应位置
在包com.dlnu.Mybatis.pojol
下放入类 Customer.java , 一个用户具有:id、username、jobs、phone四个属性。作为 mybatis 进行 sql 映射使用,与数据库表对应。代码如下:
package com.dlnu.Mybatis.pojo;public class Customer {private Integer id;private String username;private String jobs;private String phone;// 补充说明,自动生成的程序是没有构造函数的,需要的需自己添加public Customer(String username, String jobs, String phone) {super();this.username = username;this.jobs = jobs;this.phone = phone;}public Customer(Integer id, String username, String jobs, String phone) {super();this.id = id;this.username = username;this.jobs = jobs;this.phone = phone;}public Customer() {super();}// 打印对象,也需要自己添加@Overridepublic String toString() {return "Customer [Id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username == null ? null : username.trim();}public String getJobs() {return jobs;}public void setJobs(String jobs) {this.jobs = jobs == null ? null : jobs.trim();}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone == null ? null : phone.trim();} }
新建包
com.dlnu.Mybatis.dao
,并在包下放入方法接口 CustomerMapper.java ,提供简单的增删改查数据操作。代码如下:
package com.dlnu.Mybatis.dao;import java.util.List;import com.dlnu.Mybatis.pojo.Customer;public interface CustomerMapper {int delete(Integer id);int insert(Customer cust);List<Customer> query();int update(Customer cust); }
在包
com.dlnu.Mybatis.mapper
下放入映射文件 CustomerMapper.xml` ,用来定义各种 SQL 语句和这些语句的参数,以及要返回的类型等。CustomerMapper.xml写好后,需要在mybatis-config.xml文件加载它CustomerMapper.xml 的配置如下:(生成的东西很多,只根据自己需要的留下)
<?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.dlnu.Mybatis.dao.CustomerMapper"><resultMap id="BaseResultMap" type="com.dlnu.Mybatis.pojo.Customer"><id column="id" jdbcType="INTEGER" property="id" /><result column="username" jdbcType="VARCHAR" property="username" /><result column="jobs" jdbcType="VARCHAR" property="jobs" /><result column="phone" jdbcType="VARCHAR" property="phone" /></resultMap><!-- 定义 SQL 语句,其中 id 需要和接口中的方法名一致 --><!-- default:数据库中我设置id自增,所以需要默认 --><!-- parameterType 指明查询时使用的参数类型,resultType 指明查询返回的结果集类型 --><insert id="insert" parameterType="com.dlnu.Mybatis.pojo.Customer">insert into customer (id, username, jobs, phone)values (default, #{username,jdbcType=VARCHAR}, #{jobs,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR})</insert><update id="update" parameterType="com.dlnu.Mybatis.pojo.Customer">update customerset username = #{username,jdbcType=VARCHAR},jobs = #{jobs,jdbcType=VARCHAR},phone = #{phone,jdbcType=VARCHAR}where id = #{id,jdbcType=INTEGER}</update><select id="query" resultMap="BaseResultMap" >select * from customer</select><delete id="delete" parameterType="java.lang.Integer">delete from customerwhere id = #{id,jdbcType=INTEGER}</delete></mapper>
导入jar包(目录如下)
配置文件
mybatis-config.xml,用来配置 Mybatis 的运行环境、数据源、事务等。<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引用外部配置文件路径 --><properties resource="db_config.properties"></properties><!-- 实体类的别名 --><typeAliases><typeAlias type="com.dlnu.Mybatis.pojo.Customer" alias="Customer"/></typeAliases> <!-- 环境配置 --><environments default="development"> <environment id="development"><!--type="JDBC"表示使用JDBC的提交和回滚--><transactionManager type="JDBC" /><!--type="POOLED"表示支持JDBC数据库连接池 --><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}"/><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment> </environments><!--映射文件路径 --><mappers><mapper resource="com/dlnu/Mybatis/mapper/CustomerMapper.xml" /></mappers></configuration>
db_config.properties,用于存放数据库连接参数
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/mybatis username=root password=123456
log4j.properties,日志记录文件方便查看控制台输出的 SQL 语句
log4j.rootLogger=INFO, stdout log4j.logger.com.abc.mapper=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.category.org.springframework = OFF
测试。在包
com.dlnu.mybatis.test
下新建测试类TestCustomer.java
, 用来测试数据的增删改查操作。TestCustomer.java:
package com.dlnu.test import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junt.Test; import com.dlnu.Mybatis.dao.CustomerMapper; import com.dlnu.Mybatis.pojo.Customer;public class TestCustomer {// Mybatis 配置文件private String fileName = "mybatis-config.xml";// 新增客户@Testpublic void testInsert() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession sesson = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 插入数据Customer cust = new Customer("joy", "经理", "18269151234");mapper.insert(cust);// 事务需要手动提交session.commit();// 关闭连接session.close();}// 更新客户信息@Testpublic void testUpdate() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 插入数据Customer cust = new Customer(1, "lili", "Hr", "17456421562");mapper.update(cust);// 事务需要手动提交session.commit();// 关闭连接session.close();}// 删除客户@Testpublic void testDelete() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 执行删除操作mapper.delete(3);// 事务需要手动提交session.commit();// 关闭连接session.close();}// 查询所有的客户信息@Testpublic void testQuery() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 执行查询操作List<Customer> list = mapper.query();for (Customer cust : list) {System.out.println(cust);}// 关闭连接session.close();}}
测试成功!可以在数据库查看信息了。这也算是入门成功了!
配置文件
mybatis-config.xml的内容:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <!-- 引用外部配置文件路径 --><properties resource="db_config.properties"></properties><!-- 实体类的别名,将包内的 Java 类的类名作为类的类别名--><typeAliases><typeAlias type="com.dlnu.Mybatis.pojo.Customer" alias="Custmer"/></typeAliases> <!-- 环境配置 --><environments default="development"> <environment id="development"><!--type="JDBC"表示使用JDBC的提交和回滚--><transactionManager type="JDBC" /><!--type="POOLED"表示支持JDBC数据库连接池 --><!-- 数据库连接池由MyBatis管理,数据库名是mybatis --><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}"/><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment> </environments><!--映射文件路径 --><!-- 通过 mapper 接口包加载整个包的映射文件 --><mappers><mapper resource="com/dlnu/Mybatis/mapper/CustomerMapper.xml" /></mappers></configuration>
MyBatis 配置文件的 configuration 标签主要包括:
- configuration 配置
- properties 配置文件中属性值
- settings 修改 MyBat is 在运行时的行为方式
- typeAliases 为 Java 类型命名一个短名字
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- databaseIdProvider 数据库厂商标识
- mappers 映射器
下面来详细介绍在程序中出现的属性:
properties用于引用外部配置文件路径, properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件。
typeAliases 元素,与XML 配置文件相关联,减少输入多余的完整类名
<typeAliases><typeAlias type="com.dlnu.Mybatis.pojo.Customer" alias="Custmer"/></typeAliases>
在映射文件中 parameterType
和 resultType
就可以直接把长长的"com.dlnu.Mybatis.pojo.Customer"写成“Customer”
environments 环境,是对数据源的配置。MyBatis 能够配置多套运行环境,这有助于将您的SQL 映射到多个数据库上。
transactionManager:事务管理器,
MyBatis 中的两种事务管理器,即 type="[JDBC|MANAGED]":
- JDBC:直接使用 JDBC 的提交和回滚设置
- MANAGED:让容器来管理事务的整个生命周期
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。MyBatis 三种內建的数据源类型,即 type="[UNPOOLED|POOLED|JNDI]"。
- "POOLED"表示支持JDBC数据库连接池
- “UNPOOLED”表示不支持 JDBC 数据源连接池,在配置该数据源类型后,在每次被请求时打开和关闭连接。
- “JNDI”支持外部数据源连接池,可以在EJB 或应用服务器等容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。其包含的属性:
① initial_context:用来在 InitialContext 中寻找上下文
②data_source:表示引用数据源实例位置的上下文的路径
mapper映射器, 用于引用已经定义好的映射文件,告诉 MyBatis 去哪寻找映射 SQL 的语句。
映射文件
映射文件是所有 SQL 语句放置的地方,写好 SQL 语句映射文件后,需要在配置文件的 mappers 标签中引用。
在映射文件中,元素是映射文件的根元素,其他元素都是它的子元素。如下图所示:
select
select元素用来映射查询语句,它可以帮助我们从数据库中读取出数据,并组装数据给业务开发人员。
示例:
<!--查询所有数据,返回值类型是List<Customer>的,只要写集合中的类型就行了--> <select id="query" resultMap="BaseResultMap" >select * from customer</select>
我们查询出来的结果是多个对象了,所以我们使用的是以下方法:
public void testQuery() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 执行查询操作List<Customer> list = mapper.query();for (Customer cust : list) {System.out.println(cust);}// 关闭连接session.close();}
元素用于映射插入语句,在执行完元素中定义的SQL
语句后,会返回一个表示插入记录数的整数。示例:
<insert id="insert" parameterType="Customer">insert into customer (id, username, jobs, phone)values (default, #{username,jdbcType=VARCHAR}, #{jobs,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR})</insert>
调用方法:
public void testInsert() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 插入数据Customer cust = new Customer("joy", "经理", "18269151234");mapper.insert(cust);// 事务需要手动提交session.commit();// 关闭连接session.close();}
示例:
<!--根据id更新-->
<update id="update" parameterType="Customer">update customerset username = #{username,jdbcType=VARCHAR},jobs = #{jobs,jdbcType=VARCHAR},phone = #{phone,jdbcType=VARCHAR}where id = #{id,jdbcType=INTEGER}</update>
调用方法:
public void testUpdate() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 插入数据Customer cust = new Customer(1, "lili", "Hr", "17456421562");mapper.update(cust);// 事务需要手动提交session.commit();// 关闭连接session.close();}
<!--根据id删除-->
<delete id="delete" parameterType="java.lang.Integer">delete from customerwhere id = #{id,jdbcType=INTEGER}</delete>
根据id删除信息:
public void testDelete() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得dao对象CustomerMapper mapper = session.getMapper(CustomerMapper.class);// 执行删除操作mapper.delete(3);// 事务需要手动提交session.commit();// 关闭连接session.close();}
关系映射
MyBatis 的关联映射可以大大简化持久层数据的访问,关联关系的分类如下:
- 一对一:一个学号只属于一个学生,一个学生也只能有一个学号
- 一对多:一个班级有多个学生,一个学生只属于一个班级
- 多对多:一个学生可以选多门课,一门课可以有多个学生选
一对一
设计数据库表
CREATE TABLE card (c_id int(11) primary key,c_num varchar(50) );CREATE TABLE student (s_id int(11) PRIMARY KEY ,s_name varchar(20) ,s_cid int(11) ,CONSTRAINT student_fk FOREIGN KEY (s_cid) REFERENCES card (c_id) );insert into card(c_id,c_num) values (1,'10086'),(2,'10010'),(3,'10000');insert into `student(s_id,s_name,s_cid) values (1,'sam',1),(2,'tom',2),(3,'zhangsan',3);
导入jar包(目录如下)
配置文件
mybatis-config.xml,用来配置 Mybatis 的运行环境、数据源、事务等。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引用外部配置文件路径 --><properties resource="db_config.properties"></properties><!-- 实体类的别名,将包内的 Java 类的类名作为类的类别名--><typeAliases><typeAlias type="com.dlnu.humen.pojo.Card" alias="Card"/><typeAlias type="com.dlnu.humen.pojo.Student" alias="Student"/></typeAliases> <!-- 环境配置 --><environments default="development"> <environment id="development"><!--type="JDBC"表示使用JDBC的提交和回滚--><transactionManager type="JDBC" /><!--type="POOLED"表示支持JDBC数据库连接池 --><!-- 数据库连接池由MyBatis管理,数据库名是mybatis --><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}"/><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment> </environments><!--映射文件路径 --><!-- 通过 mapper 接口包加载整个包的映射文件 --><mappers><mapper resource="com/dlnu/humen/mapper/CardMapper.xml" /><mapper resource="com/dlnu/humen/mapper/StudentMapper.xml" /></mappers></configuration>
db_config.properties,用于存放数据库连接参数
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/humen username=root password=123456
log4j.properties,日志记录文件方便查看控制台输出的 SQL 语句
log4j.rootLogger=INFO, stdout log4j.logger.com.abc.mapper=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.category.org.springframework = OFF
实体,放入包com.dlnu.humen.pojo中
Card.java
package com.dlnu.humen.pojo;public class Card {private Integer cId;private String cNum;public Card() {super();}public Card(Integer cId, String cNum) {super();this.cId = cId;this.cNum = cNum;}public Integer getcId() {return cId;}public void setcId(Integer cId) {this.cId = cId;}public String getcNum() {return cNum;}public void setcNum(String cNum) {this.cNum = cNum == null ? null : cNum.trim();}@Overridepublic String toString() {return "Card [cId=" + cId + ", cNum=" + cNum + "]";}}
Student.java
package com.dlnu.humen.pojo;public class Student {private Integer sId;private String sName;private Integer sAge;private Card card;// 关联属性public Student() {super();}public Student(Integer sId, String sName, Integer sAge, Card card) {super();this.sId = sId;this.sName = sName;this.sAge = sAge;this.card = card;}public Integer getsId() {return sId;}public void setsId(Integer sId) {this.sId = sId;}public String getsName() {return sName;}public void setsName(String sName) {this.sName = sName == null ? null : sName.trim();}public Integer getsAge() {return sAge;}public void setsAge(Integer sAge) {this.sAge = sAge;}public Card getCard() {return card;}public void setCard(Card card) {this.card = card;}@Overridepublic String toString() {return "Student [sId=" + sId + ", sName=" + sName + ", sAge=" + sAge + "]";}}
映射文件,放入包com.dlnu.humen.mapper中
CardMapper.xml
<?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.dlnu.humen.dao.CardMapper" ><resultMap id="BaseResultMap" type="Card" ><id column="c_id" property="cId" jdbcType="INTEGER" /><result column="c_num" property="cNum" jdbcType="VARCHAR" /></resultMap></mapper>
StudentMapper.xml
<?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.dlnu.humen.dao.StudentMapper"><resultMap id="BaseResultMap" type="Student"><id column="s_id" jdbcType="INTEGER" property="sId" /><result column="s_name" jdbcType="VARCHAR" property="sName" /><result column="s_age" jdbcType="INTEGER" property="sAge" /><!-- 一对一关联映射:association --><association property="card" javaType="Card"><id column="c_id" property="cId" /><result column="c_num" property="cNum" /></association></resultMap><!--查询某身份证对应的学生姓名--><select id="queryByNum" parameterType="java.lang.Integer" resultMap="BaseResultMap">select s.s_name,s.s_idfrom student sleft outer join card c ON s.`s_cid`=c.`c_id`where c.c_num=#{cNum};</select> </mapper>
Dao层,放入包com.dlnu.humen.dao中
CardMapper.java
package com.dlnu.humen.dao;import com.dlnu.humen.pojo.Card;public interface CardMapper {int delete(Integer cId);int insert(Card card);Card query(Integer cId);int update(Card card); }
StudentMapper.java
package com.dlnu.humen.dao;import java.util.List;import com.dlnu.humen.pojo.Student;public interface StudentMapper {int delete(Integer sId);int insert(Student stu);List<Student> queryByNum(String cNum);int update(Student stu); }
测试,根据身份证号码查对应的学生姓名。
TestStudent.java
package com.dlnu.humen.test;import java.io.IOException; import java.io.InputStream; import java.util.List;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;import com.dlnu.humen.dao.StudentMapper; import com.dlnu.humen.pojo.Student;public class TestStudent {// Mybatis 配置文件private String fileName = "mybatis-config.xml";@Testpublic void testqueryByNum() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得mapper对象StudentMapper mapper = session.getMapper(StudentMapper.class);List<Student> list = mapper.queryByNum("10086");for (Student stu : list) {System.out.println(stu.getsName());}// 关闭连接session.close();}}
测试结果:
一对多
设计数据库表
create table student(s_id int(11) primary key,s_name varchar(20),s_age int(11),s_gid int(11),constraint student_fk foreign key(s_gid) references grade (g_id));create table grade(g_id int(11) primary key,g_name varchar(20));insert into student(s_id,s_name,s_aga,s_gid) values (1,'zhangsan',18,1),(2,'lisi',20,2),(3,'zhaowu',19,1);insert into grade(g_id,g_name) values (1,'sql'),(2,'java');select * from grade;select * from student;
实体,放入包com.dlnu.school.pojo中
Grade.java
package com.dlnu.school.pojo;/*** * 班级(单方)**/ public class Grade {private Integer gId;private String gName;public Grade() {super();}public Grade(Integer gId, String gName) {super();this.gId = gId;this.gName = gName;}public Integer getgId() {return gId;}public void setgId(Integer gId) {this.gId = gId;}public String getgName() {return gName;}public void setgName(String gName) {this.gName = gName == null ? null : gName.trim();}@Overridepublic String toString() {return "Class [gId=" + gId + ", gName=" + gName + "]";}}
Student.java
package com.dlnu.school.pojo;/*** * 学生(多方)**/public class Student {private Integer sId;private String sName;private Integer sAge;private Grade grade;// 关联属性public Student() {super();}public Student(Integer sId, String sName, Integer sAge, Grade grade) {super();this.sId = sId;this.sName = sName;this.sAge = sAge;this.grade = grade;}public Integer getsId() {return sId;}public void setsId(Integer sId) {this.sId = sId;}public String getsName() {return sName;}public void setsName(String sName) {this.sName = sName;}public Integer getsAge() {return sAge;}public void setsAge(Integer sAge) {this.sAge = sAge;}public Grade getGrade() {return grade;}public void setGrade(Grade grade) {this.grade = grade;}@Overridepublic String toString() {return "Student [sId=" + sId + ", sName=" + sName + ", sAge=" + sAge + ", grade=" + grade + "]";}}
映射文件,放入包com.dlnu.school.mapper中
GradeMapper.xml
<?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.dlnu.school.dao.GradeMapper" ><!-- resultMap: 映射实体类和字段之间的一一对应的关系 --><resultMap id="BaseResultMap" type="Grade" ><id column="g_id" property="gId" jdbcType="INTEGER" /><result column="g_name" property="gName" jdbcType="VARCHAR" /></resultMap></mapper>
StudentMapper.xml
<?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.dlnu.school.dao.StudentMapper" ><resultMap id="BaseResultMap" type="com.dlnu.school.pojo.Student" ><id column="s_id" property="sId" jdbcType="INTEGER" /><result column="s_name" property="sName" jdbcType="VARCHAR" /><result column="s_age" property="sAge" jdbcType="INTEGER" /><!-- 多对一关联班级 一个班级有多个学生 --><association property="grade" javaType="com.dlnu.school.pojo.Grade"><id column="g_id" property="gId" jdbcType="INTEGER" /><result column="g_name" property="gName" jdbcType="VARCHAR" /></association></resultMap><!--查询某班级有多少位学生--><select id="queryStuByGrade" parameterType="java.lang.String" resultMap="BaseResultMap">select s.s_name,s.s_id from student sleft OUTER JOIN grade g ON s.`s_gid`=g.`g_id`where g.g_name = #{gName};</select></mapper>
Dao层,放入包com.dlnu.school.dao中
GradeMapper.java
package com.dlnu.school.dao;import java.util.List;import com.dlnu.school.pojo.Grade;public interface GradeMapper {int delete(Integer gId);int insert(Grade grade);int update(Grade grade);List<Grade> query(); }
StudentMapper.java
package com.dlnu.school.dao;import java.util.List;import com.dlnu.school.pojo.Student;public interface StudentMapper {int delete(Integer sId);int insert(Student stu);List<Student> queryStuByGrade(String gName);int update(Student stu);List<Student> query(); }
测试,根据班级名称查班级的学生名字。因为我们主要查的是学生的信息,应把sql语句写在学生的映射文件中。
测试前请查看mybatis-config.xml和db-config.properties文件导入和是否修改相应位置,还要导入相应jar包
TestStudent.java
package com.dlnu.school.test;import java.io.IOException; import java.io.InputStream; import java.util.List;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;import com.dlnu.school.dao.StudentMapper; import com.dlnu.school.pojo.Student;public class TestStudent {// Mybatis 配置文件private String fileName = "mybatis-config.xml";@Testpublic void testqueryStuByGrade() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得mapper对象StudentMapper mapper = session.getMapper(StudentMapper.class);//查询sql班级的学生List<Student> list = mapper.queryStuByGrade("sql");for (Student student1 : list) {System.out.println(student1.getsName());}// 关闭连接session.close();}}
测试结果:
多对多
设计数据库表
CREATE TABLE course (c_id int(11) PRIMARY KEY,c_name varchar(20),`c_credit` int(11) );CREATE TABLE student (s_id int(11) PRIMARY KEY,s_name varchar(20),s_age int(11) ) ;CREATE TABLE sc (s_id int(11),c_id int(11),grade int(11) ,PRIMARY KEY (s_id,c_id),CONSTRAINT sc_ibfk_1 FOREIGN KEY (s_id) REFERENCES student (s_id),CONSTRAINT sc_ibfk_2 FOREIGN KEY (c_id) REFERENCES course (c_id) );insert into student(s_id,s_name,s_age) values (20201,'sam',20),(20202,'john',21),(20203,'lili',20);insert into course(c_id,c_name,c_credit) values (1,'sql',3),(2,'java',4),(3,'c++',2);insert into sc(s_id,c_id,grade) values (20201,3,85),(20202,2,88),(20203,1,90);
导入jar包(目录如下)
配置文件
mybatis-config.xml,用来配置 Mybatis 的运行环境、数据源、事务等。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引用外部配置文件路径 --><properties resource="db_config.properties"></properties><!-- 实体类的别名,将包内的 Java 类的类名作为类的类别名--><typeAliases><typeAlias type="com.dlnu.sc.pojo.Course" alias="Course"/><typeAlias type="com.dlnu.sc.pojo.Student" alias="Student"/><typeAlias type="com.dlnu.sc.pojo.SC" alias="SC"/></typeAliases> <!-- 环境配置 --><environments default="development"> <environment id="development"><!--type="JDBC"表示使用JDBC的提交和回滚--><transactionManager type="JDBC" /><!--type="POOLED"表示支持JDBC数据库连接池 --><!-- 数据库连接池由MyBatis管理,数据库名是mybatis --><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}"/><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment> </environments><!--映射文件路径 --><!-- 通过 mapper 接口包加载整个包的映射文件 --><mappers><mapper resource="com/dlnu/sc/mapper/CourseMapper.xml" /><mapper resource="com/dlnu/sc/mapper/StudentMapper.xml" /><mapper resource="com/dlnu/sc/mapper/SCMapper.xml" /></mappers></configuration>
db_config.properties,用于存放数据库连接参数
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/stu_course username=root password=123456
log4j.properties,日志记录文件方便查看控制台输出的 SQL 语句
log4j.rootLogger=INFO, stdout log4j.logger.com.abc.mapper=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.category.org.springframework = OFF
实体,放入包com.dlnu.sc.pojo中
Course.java
package com.dlnu.sc.pojo;import java.util.List;public class Course {private Integer cId;private String cName;private Integer cCredit;private List<Student> student;private List<SC> sc;public Course() {super();// TODO Auto-generated constructor stub}public Course(Integer cId, String cName, Integer cCredit, List<Student> student) {super();this.cId = cId;this.cName = cName;this.cCredit = cCredit;this.student = student;}public Integer getcId() {return cId;}public void setcId(Integer cId) {this.cId = cId;}public String getcName() {return cName;}public void setcName(String cName) {this.cName = cName == null ? null : cName.trim();}public Integer getcCredit() {return cCredit;}public void setcCredit(Integer cCredit) {this.cCredit = cCredit;}public List<Student> getStudent() {return student;}public void setStudent(List<Student> student) {this.student = student;}@Overridepublic String toString() {return "cId=" + cId + ", cName=" + cName + ", cCredit=" + cCredit;}}
Student.java
package com.dlnu.sc.pojo;import java.util.List;public class Student {private Integer sId;private String sName;private Integer sAge;private List<Course> courses;private List<SC> sc;public Student() {super();// TODO Auto-generated constructor stub}public Student(Integer sId, String sName, Integer sAge, List<Course> courses) {super();this.sId = sId;this.sName = sName;this.sAge = sAge;this.courses = courses;}public Integer getsId() {return sId;}public void setsId(Integer sId) {this.sId = sId;}public String getsName() {return sName;}public void setsName(String sName) {this.sName = sName == null ? null : sName.trim();}public Integer getsAge() {return sAge;}public void setsAge(Integer sAge) {this.sAge = sAge;}public List<Course> getCourses() {return courses;}public void setCourses(List<Course> courses) {this.courses = courses;}public List<SC> getSc() {return sc;}public void setSc(List<SC> sc) {this.sc = sc;}@Overridepublic String toString() {return "Student [sId=" + sId + ", sName=" + sName + ", sAge=" + sAge + ", courses=" + courses + ", sc=" + sc+ "]";}}
SC.java
package com.dlnu.sc.pojo;public class SC {private Student student;private Course course;private Integer grade;public SC() {super();// TODO Auto-generated constructor stub}public SC(Student student, Course course, Integer grade) {super();this.student = student;this.course = course;this.grade = grade;}public Integer getGrade() {return grade;}public void setGrade(Integer grade) {this.grade = grade;}public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}public Course getCourse() {return course;}public void setCourse(Course course) {this.course = course;}@Overridepublic String toString() {return "grade=" + grade;}}
映射文件,放入包com.dlnu.sc.mapper中
CourseMapper.xml
<?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.dlnu.sc.dao.CourseMapper" ><resultMap id="BaseResultMap" type="Course" ><id column="c_id" property="cId" jdbcType="INTEGER" /><result column="c_name" property="cName" jdbcType="VARCHAR" /><result column="c_credit" property="cCredit" jdbcType="INTEGER" /></resultMap></mapper>
StudentMapper.xml
<?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.dlnu.sc.dao.StudentMapper"><resultMap id="BaseResultMap" type="com.dlnu.sc.pojo.Student"><id column="s_id" jdbcType="INTEGER" property="sId" /><result column="s_name" jdbcType="VARCHAR" property="sName" /><result column="s_age" jdbcType="INTEGER" property="sAge" /><!-- 多对多关联映射:collection --><collection property="courses" ofType="Course"><id property="cId" column="c_id" /><result property="cName" column="c_name" /><result property="cCredit" column="c_credit" /></collection><!-- 多对多关联映射:collection --><collection property="sc" ofType="SC"><result property="grade" column="grade" /></collection></resultMap><!-- 查询所有学生及他们的课程的信息和成绩 --><select id="queryStudentCourse" resultMap="BaseResultMap">select s.*,c.*,sc.*from student s,course c,scwhere s.s_id=sc.s_id and c.c_id=sc.c_id</select></mapper>
SCMapper.xml
<?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.dlnu.sc.dao.SCMapper" ><resultMap id="BaseResultMap" type="SC" ><id column="s_id" property="sId" jdbcType="INTEGER" /><id column="c_id" property="cId" jdbcType="INTEGER" /><result column="grade" property="grade" jdbcType="INTEGER" /></resultMap></mapper>
Dao层,放入包com.dlnu.sc.dao中
CourseMapper.java
package com.dlnu.sc.dao;import java.util.List;import com.dlnu.sc.pojo.Course;public interface CourseMapper {int delete(Integer cId);int insert(Course course);List<Course> query(Integer cId);int update(Course course); }
StudentMapper.java
package com.dlnu.sc.dao;import java.util.List;import com.dlnu.sc.pojo.Student;public interface StudentMapper {int delete(Integer sId);int insert(Student stu);List<Student> query(Integer sId);int update(Student stu);List<Student> queryStudentCourse();}
测试,查询所有学生信息、课程信息和成绩。
测试前请查看mybatis-config.xml和db-config.properties文件导入和是否修改相应位置,还要导入相应jar包
TestStudent.java
package com.dlnu.sc.test;import java.io.IOException; import java.io.InputStream; import java.util.List;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;import com.dlnu.sc.dao.StudentMapper; import com.dlnu.sc.pojo.Student;public class TestStudent {// Mybatis 配置文件private String fileName = "mybatis-config.xml";@Testpublic void testqueryStuByGrade() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream(fileName);// 获得一个链接工厂对象 用于产生数据库连接SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获得数据库连接Session对象 (相当于Connection)SqlSession session = factory.openSession();// 获得mapper对象StudentMapper mapper = session.getMapper(StudentMapper.class);List<Student> list = mapper.queryStudentCourse();for (Student stu : list) {System.out.println(stu.toString());}// 关闭连接session.close();}}
测试结果:
快速学习MyBatis相关推荐
- 快速学习MyBatis|实战项目详解
作者主页:橙子! 主页 系列专栏:JavaWeb基础教程系列 精彩回顾:HTTP协议详解 文章目的:快速学习MyBatis及实战项目详解 文章目录 1.什么是MyBatis? 2. JDBC存在的缺点 ...
- [转载] 快速学习-Mybatis框架概述
参考链接: Java在竞争性编程中的快速I/O 第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互 ...
- 新手搭ssm要多久_如何快速学习ssm 框架?
要快速学习SSM框架,你需要一套学习曲线平滑的教程 1. 很快可以看到效果 SSM框架这种教程的,在百度或者git上一搜一大把,不过很遗憾,大部分你照着上面的流程做,是做不出来的,要么缺少包,要么配置 ...
- 快速入门mybatis(查询、添加日志、插入)
快速入门mybatis(查询.添加日志.插入) 参考学习视频网址:https://www.bilibili.com/video/BV185411s7Ry?p=9&spm_id_from=pag ...
- 我准备这样在B站快速学习Java!附上B站视频链接以及白嫖视频教程
熟悉俺的都知道,庆哥是个自学出来的Java程序员,所以嘞,私底下经常有朋友咨询关于Java自学的问题,这几天发现有这几个问题比较突出: 1.学过Java,但是不扎实 2.觉得自己Java知识体系凌乱 ...
- (*)(转)要快速学习SSM框架,你需要一套学习曲线平滑的教程
作者:meepo 链接:https://www.zhihu.com/question/57719761/answer/156952139 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商 ...
- 业余快速学习虚幻引擎教程
仅用5小时学会虚幻引擎! 你会学到什么 专为希望在业余时间打造虚幻引擎技能的艺术家和开发人员量身定制的专业技术 从几何图形到材料,从照明到互动,所有方面的提示 探索如何创造建筑水的效果 如何使用顶点绘 ...
- 零基础快速学习Java技术的方法整理
在学习java技术这条道路上,有很多都是零基础学员,他们对于java的学习有着很多的不解,不知怎么学习也不知道如何下手,其实Java编程涉及到的知识点还是非常多的,我们需要制定java学习路线图这样才 ...
- 怎样快速学习html5,如何快速学习HTML5?带你了解HTML5学什么?
今天小编要为大家分享的文章是关于如何快速学习HTML5?HTML5主要学些什么的文章.近年来前端开发非常热门,前端开发工程师也很稀缺,于是很多人将其视为高薪行业的代名词.HTML5前端开发工程师被称作 ...
最新文章
- 在ROS使用奥比中光Orbbec Astra Pro
- 性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库
- 大话PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置...
- Dev-C++ v5.11
- 微分算子为什么也是空间滤波器
- 白色裤子为什么会沾上蓝色_什么是蓝色的,为什么它可以在Mac上运行?
- C++ class中的静态(static)成员
- scala 基础 ——关键字与特殊符号
- 戴尔t40服务器接显示器,Dell PowerEdge T40 机架式服务器
- QT 播放器之VideoWidget
- 字符编码——简体中文编码中区位码、国标码、内码、外码、字形码的区别及关系
- 电信中兴f452光猫路由改桥接最简单的方式,亲自体验成功。
- Tbase 源码 (五)
- 计算机课程word教学,Word教学方法及使用技巧
- 登录邮箱用哪个好,好用的登录邮箱推荐
- 直接获得TP-LINK路由器外网IP地址
- 辨析NOR FLASH地址左右移的问题
- 熵值法的python实现方法
- 晶体三极管及其基本放大电路之共发射极电路
- CC254x/CC2540/CC2541库函数速查
热门文章
- 引领设计趋势!最新潮的24个获奖网页作品欣赏
- Unity简单商城系统,用SQLite数据库保存/加载数据
- 在线转换,直接将dwg转换成jpg
- OpenStack Train Magnum部署Kubernetes(2)--使用OpenStack界面部署虚拟机
- 基于PHP的自动化售货系统(简洁优雅)
- uniapp 底部菜单_利用uni-app怎么对底部导航栏进行自定义
- Vue简单入门学习-----day1-基础用法
- 港口起重机PLC远程监控.PLC远程编程.PLC数据采集管理系统
- linux读写nvram,openwrt - NVRAM集合
- linux下的c语言实现象棋,用c语言+API制作象棋界面