1.建立maven项目
2.首先引入mybatis
需要引入的依赖(1).数据库驱动(2).mybatis核心包 <!-- mysql数据库驱动--> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>3.1.14</version> </dependency> <!-- mybatis核心包--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency>3.在classpath下创建log4j.properties如下:# Global logging configurationlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%nmybatis默认使用log4j作为输出日志信息。
4.配置SqlMapConfig.xml
在classpath下创建SqlMapConfig.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><!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"><!-- 使用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="" /> <property name="password" value="" /> </dataSource> </environment> </environments></configuration>SqlMapConfig.xml是mybatis核心配置文件,上边文件的配置内容为数据源、事务管理。
5.pojo类Po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java如下:Public class User { private int id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 get/set……}6.sql映射文件在classpath下的sqlmap目录下创建sql映射文件Users.xml:<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="test"></mapper>namespace :命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。
7.加载映射文件mybatis框架需要加载映射文件,将Users.xml添加在SqlMapConfig.xml,如下:<mappers> <mapper resource="sqlmap/User.xml"/></mappers>例如
根据id查询用户信息:
注意:在idea中配置文件必须放在配置文件夹中,放在普通文件夹或类文件夹下均不读取
在user.xml中添加:
<!-- 根据id获取用户信息 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select>parameterType:定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。resultType:定义结果映射类型。测试程序:public class Mybatis_first { //会话工厂 private SqlSessionFactory sqlSessionFactory;@Before
public void createSqlSessionFactory() throws IOException { // 配置文件 String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource);// 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream);}
// 根据 id查询用户信息
@Test public void testFindUserById() { // 数据库会话实例 SqlSession sqlSession = null; try { // 创建数据库会话实例sqlSession sqlSession = sqlSessionFactory.openSession(); // 查询单个记录,根据用户id查询用户信息 User user = sqlSession.selectOne("test.findUserById", 10); // 输出用户信息 System.out.println(user); } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) { sqlSession.close(); } }}
}#{}和${}#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
selectOne和selectList
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)selectList可以查询一条或多条记录。使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
(1)原始Dao开发方法配置
原始Dao开发方法需要程序员编写Dao接口和Dao实现类。映射文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="test"><!-- 根据id获取用户信息 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select><!-- 添加用户 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert></mapper>Dao接口Public interface UserDao { public User getUserById(int id) throws Exception; public void insertUser(User user) throws Exception;}=============================================================================Public class UserDaoImpl implements UserDao { //注入SqlSessionFactory public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.setSqlSessionFactory(sqlSessionFactory); } private SqlSessionFactory sqlSessionFactory; @Override public User getUserById(int id) throws Exception { SqlSession session = sqlSessionFactory.openSession(); User user = null; try { //通过sqlsession调用selectOne方法获取一条结果集 //参数1:指定定义的statement的id,参数2:指定向statement中传递的参数 user = session.selectOne("test.findUserById", 1); System.out.println(user); } finally{ session.close(); } return user; } @Override Public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.insert("insertUser", user); sqlSession.commit(); } finally{ session.close(); } }} Dao测试创建一个JUnit的测试类,对UserDao进行测试。private SqlSessionFactory sqlSessionFactory; @Before public void init() throws Exception { SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder(); InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); sqlSessionFactory = sessionFactoryBuilder.build(inputStream); }@Test
public void testGetUserById() { UserDao userDao = new UserDaoImpl(sqlSessionFactory); User user = userDao.getUserById(22); System.out.println(user); }}原始Dao开发中存在以下问题:Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。(2)Mapper动态代理方式
开发规范:Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。Mapper接口开发需要遵循以下规范:1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同Mapper.xml(映射文件)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.itcast.mybatis.mapper.UserMapper"><!-- 根据id获取用户信息 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select><!-- 自定义条件查询用户列表 --> <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select><!-- 添加用户 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert></mapper>
Mapper.java(接口文件)/** * 用户管理mapper */Public interface UserMapper { //根据用户id查询用户信息 public User findUserById(int id) throws Exception; //查询用户列表 public List<User> findUserByUsername(String username) throws Exception; //添加用户信息 public void insertUser(User user)throws Exception; }加载UserMapper.xml文件
修改SqlMapConfig.xml文件: <!-- 加载映射文件 --> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers>测试Public class UserMapperTest extends TestCase {private SqlSessionFactory sqlSessionFactory;
@Before public void setUp() throws Exception { //mybatis配置文件 String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); //使用SqlSessionFactoryBuilder创建sessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); }@Test
Public void testFindUserById() throws Exception { //获取session SqlSession session = sqlSessionFactory.openSession(); //获取mapper接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); //调用代理对象方法 User user = userMapper.findUserById(1); System.out.println(user); //关闭session session.close(); } @Test public void testFindUserByUsername() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> list = userMapper.findUserByUsername("张"); System.out.println(list.size());}
Public void testInsertUser() throws Exception { //获取session SqlSession session = sqlSessionFactory.openSession(); //获取mapper接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); //要添加的数据 User user = new User(); user.setUsername("张三"); user.setBirthday(new Date()); user.setSex("1"); user.setAddress("北京市"); //通过mapper接口添加用户 userMapper.insertUser(user); //提交 session.commit(); //关闭session session.close(); }}
namespacemybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。总结:SqlMapConfig.xml配置文件内容与顺序properties(属性)settings(全局配置参数)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境集合属性对象)environment(环境子属性对象)transactionManager(事务管理)dataSource(数据源)mappers(映射器)