MyBatis
简介
什么是 MyBatis ?
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录,且是ibatis的进一步完善和升级。
XML 配置文件(configuration XML)中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。
environment 元素体中包含了事务管理和连接池的配置。mappers 元素则是包含一组 mapper 映射器(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息)。
Mybatis案例
导包:
表的实体User
package mybatis.model; public class User { private int id; private String username; private String password; 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 String getPassword() { return password;} public void setPassword(String password) { this.password = password;} public User() {} public User( String username, String password) { this.username = username; this.password = password;} @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]";}} |
Mybatis配置文件
<?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"><!-- 默认调用那个 --> <environment id="development"><!-- 可以有很多的所以同过ID来使用 --> <transactionManager type="JDBC"/><!-- 事务管理器 --> <!-- 数据源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mynew"/> <property name="username" value="root"/> <property name="password" value="ROOT"/> </dataSource> </environment> </environments> <!-- 配置映射 --> <mappers> <mapper resource="mybatis/mapper/usermapper.xml"/><!—指定映射文件的全部路径(包名+文件名)--> </mappers> </configuration> |
Mybatis文件的映射文件(具体操作)
<?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="mybatis.model.User"><!-- 最好和实体类保持一致 --> <!-- 新增 --> <insert id="add" parameterType="map"><!—指定所需的属性类型为Map集合--> <!—如这边需要两个参数,需要指定值的对应所以选用map集合--> insert into user(username,password) values(#{username},#{password}) </insert> <!--添加 --> <update id="update" parameterType="map"> update user set username=#{username},password=#{password} where id=#{id} </update> <!-- 删除 --> <delete id="del" parameterType="Integer"> delete from user where id=#{id} </delete> <!-- 单对象查询 --> <select id="load" resultType="mybatis.model.User"> select *from user where id= #{id} </select> <!-- 集合查询 --> <select id="list" resultType="mybatis.model.User"> select *from user </select> <!-- 分页查询 --> <select id="pagelist" resultType="mybatis.model.User"> select *from user limit #{0ffSet},#{pageSize} </select> <!-- 分页排序查询 --> <select id="page" resultType="mybatis.model.User"> select *from user order by ${order} ${sort} limit #{0ffSet},#{pageSize} </select> </mapper> |
Test测试
package mybatis.mapper.Test; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class Test { @org.junit.Test public void Test() throws IOException{ //加载配置文件 InputStream is= Resources.getResourceAsStream("mybatis.xml"); //获取sqlsessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //获取sqlsession和打开 SqlSession session= factory.openSession(); //执行操作 Map<String, Object> params=new HashMap<String,Object>(); params.put("username","asd"); params.put("password","asd"); session.insert("mybatis.model.User.add",params); //提交事务 session.commit(); } //测试添加 @org.junit.Test public void Test2() throws IOException{ //加载配置文件 InputStream is= Resources.getResourceAsStream("mybatis.xml"); //获取sqlsessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //获取sqlsession和打开 SqlSession session= factory.openSession(); //执行操作 Map<String, Object> params=new HashMap<String,Object>(); params.put("username","asd"); params.put("password","asdasd"); params.put("id", "3"); session.update("mybatis.model.User.update",params); //提交事务 session.commit(); } @org.junit.Test public void del() throws IOException{ InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession(); session.delete("mybatis.model.User.del",4); session.commit(); } } |
因为里面有一些重复的代码所以,可以将一些操作提取出来
工具类;
package mybatis.until; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; /** * @author lx * */ public class BasDao { static SqlSessionFactory factory=null; static{ //加载配置文件 InputStream is; try { is = Resources.getResourceAsStream("mybatis.xml"); factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); } } /** * 打开session * @return */ public static SqlSession getSession(){ return factory.openSession(); } /** * 关闭session */ public static void close(SqlSession session){ if(session !=null){ session.close(); } } } |
Test测试:
package mybatis.mapper.Test; import java.util.HashMap; import java.util.Map; import mybatis.model.User; import mybatis.until.BasDao; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class myTest { @Test public void add(){ //获取session SqlSession session = BasDao.getSession(); //设置参数 Map<String, Object> params=new HashMap<String,Object>(); params.put("username","asd"); params.put("password","asd"); //执行操作 session.insert("mybatis.model.User.add",params); //提交事务 session.commit(); //关闭资源 BasDao.close(session); } @Test public void update(){ Map<String, Object> params=new HashMap<String,Object>(); //获取session SqlSession session = BasDao.getSession(); //设置参数 params.put("username","asd"); params.put("password","asdasd"); params.put("id", "6"); //获取的和mybatis.model.User.update第一样 session.update(User.class.getName()+".update",params); //提交事务 session.commit(); //关闭资源 BasDao.close(session); } @Test public void del(){ //获取session SqlSession session = BasDao.getSession(); session.delete(User.class.getName()+".del",6); //提交事务 session.commit(); //关闭资源 BasDao.close(session); } } |
Test:查询的测试:
package mybatis.mapper.Test; import java.util.HashMap; import java.util.List; import java.util.Map; import mybatis.model.User; import mybatis.until.BasDao; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class TestSelect { /** * 简单查询,对于单个对象的查询 */ @Test public void testload(){ SqlSession session = BasDao.getSession(); User user = session.selectOne(User.class.getName()+".load",2); System.out.println(user); BasDao.close(session); } /** * 查询表中所有的信息 */ @Test public void testlist(){ SqlSession session = BasDao.getSession(); List<User> users = session.selectList(User.class.getName()+".list"); for(User u:users){ System.out.println(u); } BasDao.close(session); } /** * 查询分页 */ @Test public void testfen(){ SqlSession session = BasDao.getSession(); Map<String,Object> map = new HashMap<String ,Object>(); map.put("0ffSet", 0); map.put("pageSize", 3); List<User> users = session.selectList(User.class.getName()+".pagelist",map); for(User u:users){ System.out.println(u); } BasDao.close(session); } /** * 分页排序查询 */ @Test public void testfenfenzu(){ SqlSession session = BasDao.getSession(); Map<String,Object> map = new HashMap<String ,Object>(); map.put("0ffSet", 0); map.put("order","id"); map.put("sort", "desc"); map.put("pageSize", 4); List<User> users = session.selectList(User.class.getName()+".page",map); for(User u:users){ System.out.println(u); } BasDao.close(session); } } |
#:根据参数类型来设置
$:直接使用参数,不进行任何的转义,有sql注入的风险
properties
这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递
typeAliases
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
更改3
Mybaits:
<?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> <!--properties加载文件 --> <properties resource="jdbc.properties" /> <!-- 设置别名 --> <typeAliases ><!-- 位置一定要按照指定的规则来放置 --> <!-- <typeAlias alias="User" type="mybatis.model.User"/>可以书写多个 -->
<!--通常使用多个的时候, 基于包来设置别名 --> <package name="mybatis.model"/> <!-- 默认使用包中的类名,为别名如:User --> </typeAliases> <environments default="development"><!-- 默认调用那个 --> <environment id="development"><!-- 可以有很多的所以同过ID来使用 --> <transactionManager type="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="mybatis/mapper/usermapper.xml"/> </mappers> </configuration> |
映射文件
<?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="mybatis.model.User"><!-- 最好和实体类保持一致 --> <!-- 新增 --> <insert id="add" parameterType="map"> insert into user(username,password) values(#{username},#{password}) </insert> <!--添加 --> <update id="update" parameterType="map"> update user set username=#{username},password=#{password} where id=#{id} </update> <!-- 删除 --> <delete id="del" parameterType="Integer"> delete from user where id=#{id} </delete>
<!-- 单对象查询 --> <select id="load" resultType="User"><!-- 调用前面定义的User类型不区分大小写 --> select *from user where id= #{id} </select>
<!-- 集合查询 --> <select id="list" resultType="User"> select *from user </select> <!-- 分页查询 --> <select id="pagelist" resultType="User"> select *from user limit #{0ffSet},#{pageSize} </select> <!-- 分页排序查询 --> <select id="page" resultType="User"> select *from user order by ${order} ${sort} limit #{0ffSet},#{pageSize} </select>
</mapper> |
基于接口的实现
映射器(mappers)
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等
UserMapper接口
package mybatis.ma; import java.util.List; import mybatis.model.User; public interface UserMapper { /** * 接口中的方法与usermapper.xml文件 id相对应 */ void add(User user); void update(User user); void del(int id); public User load(int id); public List<User>list(); public List<User>pagelist(); public List<User>page(); public int count();} |
Usermapper.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="mybatis.ma.UserMapper"><!--接口类的全名 --> <!-- 新增 --> <insert id="add" parameterType="User"> insert into user(username,password) values(#{username},#{password}) </insert> <!--添加 --> <update id="update" parameterType="User"> update user set username=#{username},password=#{password} where id=#{id} </update> <!-- 删除 --> <delete id="del" parameterType="int"> delete from user where id=#{id} </delete> <!-- 单对象查询 --> <select id="load" resultType="User"><!-- 调用前面定义的User类型不区分大小写 --> select *from user where id= #{id} </select> <!-- 集合查询 --> <select id="list" resultType="User"> select *from user </select> <!-- 分页查询 --> <select id="pagelist" resultType="User"> select *from user limit #{0ffSet},#{pageSize} </select> <!-- 分页排序查询 --> <select id="page" resultType="User"> select *from user order by ${order} ${sort} limit #{0ffSet},#{pageSize} </select> <!-- 查询个数 --> <select id="count" resultType="java.lang.Integer"> select count(*) from user </select> </mapper> |
Mybatis.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> <!--properties加载文件 --> <properties resource="jdbc.properties" /> <!-- 设置别名 --> <typeAliases ><!-- 位置一定要按照指定的规则来放置 --> <!-- <typeAlias alias="User" type="mybatis.model.User"/>可以书写多个 --> <!--通常使用多个的时候, 基于包来设置别名 --> <package name="mybatis.model"/> <!-- 默认使用包中的类名,为别名如:User --> </typeAliases> <environments default="development"><!-- 默认调用那个 --> <environment id="development"><!-- 可以有很多的所以同过ID来使用 --> <transactionManager type="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="mybatis/mapper/usermapper.xml"/> </mappers> </configuration> |
测试:
package mybatistwo.UserImp; import java.util.List; import mybatistwo.BasDao.UserDao; import mybatistwo.mapper.UserMapper; import mybatistwo.model.User; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class UserImp { /** * 用户个数统计 */ @Test public void Testcount(){ SqlSession session = UserDao.getSession(); int i = session.getMapper(UserMapper.class).count(); System.out.println(i); UserDao.close(session); } /** * 添加 */ @Test public void TESADD(){ SqlSession session = UserDao.getSession(); User user = new User("冬","asdas"); session.getMapper(UserMapper.class).add(user); session.commit(); UserDao.close(session); } /** * 更改 */ @Test public void TESupdate(){ SqlSession session = UserDao.getSession(); User user = new User(); user.setId(8); user.setPassword("ass"); user.setUsername("asdasd"); session.getMapper(UserMapper.class).update(user); session.commit(); UserDao.close(session); } /** * 删除 */ @Test public void TESdel(){ SqlSession session = UserDao.getSession(); session.getMapper(UserMapper.class).del(7); session.commit(); UserDao.close(session); } /** * 查询单个对象 */ @Test public void TESelect(){ SqlSession session = UserDao.getSession(); User user = session.getMapper(UserMapper.class).load(2); System.out.println(user); UserDao.close(session); } /** * 查询所有用户 */ @Test public void TElist(){ SqlSession session = UserDao.getSession(); List<User> list = session.getMapper(UserMapper.class).list(); for(User u:list){ System.out.println(u); } UserDao.close(session); } } |