一直在使用,从未系统的总结起来。因此这里给你们带来的是mybatis的总结,系统你们可以对这个框架有必定的系统的学习与认识。
mybatis和Hibernate应该是如今主流的ORM框架了。
mybatis学习的步骤:
mybatis入门 --> 全局配置文件和映射文件详解 --> 高级映射(一对一,一对多,多对多) -->延迟加载机制 -->一级缓存,
二级缓存(整合ehcache) --> spring整合mybatis --> 逆向工程java
总结一下:mysql
MyBatis 是来和数据库打交道。那么在这以前,咱们是使用 JDBC 来对数据库进行增删改查等一系列操做的,而咱们之因此会放弃
使用 JDBC,转而使用 MyBatis 框架,这是为何呢?
为何使用Mybatis比JDBC直接链接方便和性能上好不少呢?spring
public class Person { private Long pid; private String pname; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } }
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.swing.DebugGraphics; import com.ys.bean.Person; public class CRUDDao { //MySQL数据库驱动 public static String driverClass = "com.mysql.jdbc.Driver"; //MySQL用户名 public static String userName = "root"; //MySQL密码 public static String passWord = "654321"; //MySQL URL public static String url = "jdbc:mysql://localhost:3306/study"; //定义数据库链接 public static Connection conn = null; //定义声明数据库语句,使用 预编译声明 PreparedStatement提升数据库执行性能 public static PreparedStatement ps = null; //定义返回结果集 public static ResultSet rs = null; /** * 查询 person 表信息 * @return:返回 person 的 list 集合 */ public static List<Person> readPerson(){ List<Person> list = new ArrayList<>(); try { //加载数据库驱动 Class.forName(driverClass); //获取数据库链接 conn = DriverManager.getConnection(url, userName, passWord); //定义 sql 语句,?表示占位符 String sql = "select * from person where pname=?"; //获取预编译处理的statement ps = conn.prepareStatement(sql); //设置sql语句中的参数,第一个为sql语句中的参数的?(从1开始),第二个为设置的参数值 ps.setString(1, "qzy"); //向数据库发出 sql 语句查询,并返回结果集 rs = ps.executeQuery(); while (rs.next()) { Person p = new Person(); p.setPid(rs.getLong(1)); p.setPname(rs.getString(2)); list.add(p); } } catch (Exception e) { e.printStackTrace(); }finally{ //关闭数据库链接 if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return list; } public static void main(String[] args) { System.out.println(CRUDDao.readPerson()); } }
建立完成,随便写几条数据进去。sql
备注:log4j和Junit不是必须的,可是咱们为了查看日志以及便于测试,加入了这两个jar包
目录结构:
数据库
<?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标签,当mybatis和spring整合以后,这个标签是不用配置的 --> <!-- 能够配置多个运行环境,可是每一个 SqlSessionFactory 实例只能选择一个运行环境 1、development:开发模式 2、work:工做模式--> <environments default="development"> <!--id属性必须和上面的default同样 --> <environment id="development"> <!--事务管理器 1、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源获得的链接来管理事务范围 2、MANAGED:这个配置几乎没作什么。它历来不提交或回滚一个链接。而它会让容器来管理事务的整个生命周期 好比 spring 或 JEE 应用服务器的上下文,默认状况下,它会关闭链接。然而一些容器并不但愿这样, 所以若是你须要从链接中中止它,就能够将 closeConnection 属性设置为 false,好比: <transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager> --> <transactionManager type="JDBC"/> <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 链接对象源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/study"/> <property name="username" value="root"/> <property name="password" value="654321"/> </dataSource> </environment> </environments> <mappers> <!-- 注册userMapper.xml文件, userMapper.xml位于com.lance.mybatis这个包下,因此resource写成com/lance/mybatis/userMapper.xml--> <mapper resource="com/lance/mybatis/mapper/userMapper.xml"/> </mappers> </configuration>
package com.lance.mybatis.bean; import java.util.Date; public class User { private int id; private String username; private int password; private String sex; private Date birthday; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getPassword() { return password; } public void setPassword(int password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password=" + password + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}'; } }
<?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.lance.mybatis.mapper.userMapper"> <!-- 根据 id 查询 user 表中的数据 id:惟一标识符,此文件中的id值不能重复 resultType:返回值类型,一条数据库记录也就对应实体类的一个对象 parameterType:参数类型,也就是查询条件的类型 --> <select id="selectUserById" resultType="com.lance.mybatis.bean.User" parameterType="int"> <!-- 这里和普通的sql 查询语句差很少,后面的 #{id}表示占位符,里面不必定要写id,写啥均可以,可是不要空着 --> select * from user where id = #{id} </select> <!-- 查询 user 表的全部数据 注意:由于是查询全部数据,因此返回的应该是一个集合,这个集合里面每一个元素都是User类型 --> <select id="selectUserAll" resultType="com.lance.mybatis.bean.User"> select * from user </select> <!-- 模糊查询:根据 user 表的username字段 下面两种写法均可以,可是要注意 一、${value}里面必需要写value,否则会报错 二、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中 三、使用${}会形成 sql 注入 --> <select id="selectLikeUserName" resultType="com.lance.mybatis.bean.User" parameterType="String"> select * from user where username like '%${value}%' <!-- select * from user where username like #{username} --> </select> <!-- 向 user 表插入一条数据 --> <insert id="insertUser" parameterType="com.lance.mybatis.bean.User"> <!-- 将插入的数据主键返回到 user 对象中 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性 select LAST_INSERT_ID():查询上一次执行insert 操做返回的主键id值,只适用于自增主键 resultType:指定 select LAST_INSERT_ID() 的结果类型 order:AFTER,相对于 select LAST_INSERT_ID()操做的顺序 --> <selectKey keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into user(username,password,sex,birthday,address) value(#{username},#{password},#{sex},#{birthday},#{address}) </insert> <!-- 根据 id 更新 user 表的数据 --> <update id="updateUserById" parameterType="com.lance.mybatis.bean.User"> update user set username=#{username} where id=#{id} </update> <!-- 根据 id 删除 user 表的数据 --> <delete id="deleteUserById" parameterType="int"> delete from user where id=#{id} </delete> </mapper>
package com.lance.mybatis.test; import com.lance.mybatis.bean.User; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.Date; import java.util.List; /** * @author lance(ZYH) * @function * @date 2018-07-07 21:10 */ public class MybatisTest { SqlSession session = null; @Before public void init() { //定义mybatis全局配置文件 String resource = "com/lance/mybatis/config/mybatis-configuration.xml"; //加载 mybatis 全局配置文件 InputStream inputStream = MybatisTest.class.getClassLoader() .getResourceAsStream(resource); //构建sqlSession的工厂 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //根据 sqlSessionFactory 产生 session session = sessionFactory.openSession(); } //根据id查询user表数据 @Test public void getUserById() { /*这个字符串由 userMapper.xml 文件中 两个部分构成 <mapper namespace="com.lance.mybatis.userMapper"> 的 namespace 的值 <select id="selectUserById" > id 值*/ String statement = "com.lance.mybatis.mapper.userMapper.selectUserById"; User user = session.selectOne(statement, 1); System.out.println(user); session.close(); } //查询全部user表全部数据 @Test public void testSelectUserAll() { String statement = "com.lance.mybatis.mapper.userMapper.selectUserAll"; List<User> listUser = session.selectList(statement); for (User user : listUser) { System.out.println(user); } session.close(); } //模糊查询:根据 user 表的username字段 @Test public void testSelectLikeUserName(){ String statement = "com.lance.mybatis.mapper.userMapper.selectLikeUserName"; List<User> listUser = session.selectList(statement, "%张%"); for(User user : listUser){ System.out.println(user); } session.close(); } //向 user 表中插入一条数据 @Test public void testInsertUser(){ String statement = "com.lance.mybatis.mapper.userMapper.insertUser"; User user = new User(); user.setUsername("刘美玲"); user.setPassword(98766); user.setSex("女"); user.setAddress("河南省啥子去"); session.insert(statement, user); //提交插入的数据 session.commit(); session.close(); } //根据 id 更新 user 表的数据 @Test public void testUpdateUserById(){ String statement = "com.lance.mybatis.mapper.userMapper.updateUserById"; //若是设置的 id不存在,那么数据库没有数据更改 User user = new User(); user.setId(4); user.setUsername("jim"); session.update(statement, user); session.commit(); session.close(); } //根据 id 删除 user 表的数据 @Test public void testDeleteUserById(){ String statement = "com.lance.mybatis.mapper.userMapper.deleteUserById"; session.delete(statement,4); session.commit(); session.close(); } }
1)数据库设置主键自增机制
userMapper.xml 文件中定义:apache
<!-- 向 user 表插入一条数据 --> <insert id="insertUser" parameterType="com.ys.po.User"> <!-- 将插入的数据主键返回到 user 对象中 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性 select LAST_INSERT_ID():查询上一次执行insert 操做返回的主键id值,只适用于自增主键 resultType:指定 select LAST_INSERT_ID() 的结果类型 order:AFTER,相对于 select LAST_INSERT_ID()操做的顺序 --> <selectKey keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into user(username,password,sex,birthday,address) value(#{username},#{password},#{sex},#{birthday},#{address}) </insert>
2)非自增主键机制缓存
<!-- 向 user 表插入一条数据 --> <insert id="insertUser" parameterType="com.ys.po.User"> <!-- 将插入的数据主键返回到 user 对象中 流程是:首先经过 select UUID()获得主键值,而后设置到 user 对象的id中,在进行 insert 操做 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性 select UUID():获得主键的id值,注意这里是字符串 resultType:指定 select UUID() 的结果类型 order:BEFORE,相对于 select UUID()操做的顺序 --> <selectKey keyProperty="id" resultType="String" order="BEFORE"> select UUID() </selectKey> insert into user(id,username,passwor,sex,birthday,address) value(#{id},#{username},#{password},#{sex},#{birthday},#{address}) </insert>