1. MyBatis认识
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis可以使用简单的XML配置或注解来配置和映射原生信息,将接口和Java的POJO(Plain Ordinary Java Object,普通Java对象)映射成数据库中的数据。
2. 使用MyBatis完成基础的CRUD 2.1.导入对应MyBatis及数据库连接jar包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
mybatis-3.2.1.jar
mysql-connector-java-5.1.26-bin.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
2.2.建立数据库的表
2.3. 对应数据库表创建Domain类
public class Product {private Long id;private Long dir_id; // 商品分类编号private String productName;// 商品名称private String supplier; // 供应商private String brand; // 品牌private Double salePrice; // 零售价private Double cutoff; // 折扣比例private Double costPrice; // 进价。。。。// Getter与Setter略过}
2.4. 配置MyBatis核心配置文件
MyBatis的核心配置文件放在项目的资源文件resources目录下,文件命名为mybatis-config.xml,具体的配置如下:
mybatis-config.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> 引入jdbc.properties配置文件 --><properties resource="jdbc.properties">properties>别名的配置,类的全限定名可以使用别名 alias:别名名称 type:别名所对应的类的全限定名,别名的使用与大小写无关--><typeAliases><typeAlias alias="Product" type="cn.yif.mybatis.domain.Product">typeAlias><typeAlias alias="User" type="cn.yif.mybatis.domain.User">typeAlias>typeAliases>MyBatis环境配置--><environments default="development"><environment id="development"><transactionManager type="JDBC"/> 数据库连接配置 --><dataSource type="POOLED"><property name="driver" value="${driverClassName}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/>dataSource>environment>environments><!—- Mapper.xml文件配置 --><mappers><mapper resource="cn/yif/mybatis/mapper/ProductMapper.xml"/><mapper resource="cn/yif/mybatis/mapper/UserMapper.xml"/>mappers>configuration>
2.5. 关联jdbc.properties文件配置
driverClassName = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/mybatis01_0317 username = root password = admin
2.6. 对象关系映射文件XXXMapper.xml
映射文件XXXMapper.xml是对应Domain属性与DaoImpl中方法并与数据库字段产生关系的唯一映射配置,在这里面我们可以存放基础的CRUD对应的Sql文件,去执行数据库的操作:
<?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"> namespace:用来找唯一的mapper文件,一般是domain的全路径名+Mapper来命名 --><mapper namespace="cn.yif.mybatis.domain.Product">id表示唯一标识,parameterType标识参数的类型,resultType表示返回值的类型--><select id="queryById" parameterType="Long" resultType="cn.yif.mybatis.domain.Product">select * from Product where id = #{id}select><select id="queryAll" resultType="cn.yif.mybatis.domain.Product">select * from Productselect>添加时拿到返回的主键: parameterType:需要传入的对象 useGeneratedKeys:是否需要主键 keyColumn:数据库中对应主键的列 keyProperty:对象中主键对应的id--> <insert id="insert" parameterType="cn.yif.mybatis.domain.Product" useGeneratedKeys="true"keyColumn="id" keyProperty="id"> insert into Product(productName, dir_id, salePrice, supplier, brand, cutoff, costPrice) values (#{productName}, #{dir_id}, #{salePrice}, #{supplier}, #{brand}, #{cutoff}, #{costPrice})insert><update id="update" parameterType="cn.yif.mybatis.domain.Product">update product set productName = #{productName}, dir_id = #{dir_id}, salePrice = #{salePrice}, supplier = #{supplier}, brand = #{brand}, cutoff = #{cutoff}, costPrice = #{costPrice} where id = #{id}update><delete id="delete" parameterType="Long">delete from product where id = #{id}delete>mapper>
2.7. 获取SqlSession对象并抽取工具Util类
首先我们需要读取mybatis-config.xml核心资源文件,通过SqlSessionFactoryBuilder构建者来创建一个SqlSessionFactory工厂,通过SqlSessionFactory来创建SqlSession对象。通过SqlSession就可以执行我们的数据库增删查改的xml中的配置语句,最终使用之后还需要及时关闭SqlSession语句对象。基于这种增删改查操作都是同样的我们可以抽取一个工具类MyBatisUtil,具体实现如下:
public class MyBatisUtil {private static SqlSessionFactory sqlSessionFactory = null;private static Reader reader = null;// 因为sqlSessionFactory是线程安全的,每次初始化只需要创建一个SqlSessionFactory实例static {try { reader = Resources.getResourceAsReader("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { e.printStackTrace(); } }// SqlSession是线程不安全的类,每个线程内单独去获取当前线程的SqlSessionpublic static SqlSession getSqlSession(){return sqlSessionFactory.openSession(); }// 关闭SqlSessionpublic static void closeSqlSession(SqlSession sqlSession){if(sqlSession != null){ sqlSession.close(); } } }
2.8. 对应实现增删查改的DaoImpl代码
ProductDaoImpl.java
public class ProductDaoImpl implements IProductDao {public static final String NAME_SPACE = "cn.yif.mybatis.domain.Product."; @Overridepublic void insert(Product product) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); sqlSession.insert(NAME_SPACE + "insert", product); MyBatisUtil.closeSqlSession(sqlSession); } @Overridepublic void update(Product product) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); sqlSession.update(NAME_SPACE + "update", product); MyBatisUtil.closeSqlSession(sqlSession); } @Overridepublic void delete(Long id) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); sqlSession.delete(NAME_SPACE + "delete", id); MyBatisUtil.closeSqlSession(sqlSession); } @Overridepublic Product queryById(Long id) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); Product product = sqlSession.selectOne(NAME_SPACE + "queryById", id); MyBatisUtil.closeSqlSession(sqlSession);return product; } @Overridepublic List queryAll() { SqlSession sqlSession = MyBatisUtil.getSqlSession(); Listlist = sqlSession.selectList(NAME_SPACE + "queryAll"); MyBatisUtil.closeSqlSession(sqlSession);return list; } }
2.9. 对应Junit4测试类实现
public class ProductDaoImplTest { @org.junit.Testpublic void insert() { IProductDao productDao = new ProductDaoImpl(); Product product = new Product(); product.setProductName("测试产品112"); product.setBrand("TestBrand"); product.setCostPrice(237.5); product.setCutoff(0.85); product.setDir_id(4L); product.setSalePrice(520.0); product.setSupplier("甲骨文"); System.out.println("添加之前,查看id:" + product.getId()); productDao.insert(product); System.out.println("添加之后,查看id:" + product.getId()); } @org.junit.Testpublic void update() { IProductDao productDao = new ProductDaoImpl(); Product product = new Product(); product.setId(22L); product.setProductName("测试产品114"); product.setBrand("TestBrand114"); product.setCostPrice(237.1); product.setCutoff(0.45); product.setDir_id(4L); product.setSalePrice(520.1); product.setSupplier("甲骨文114"); productDao.update(product); } @org.junit.Testpublic void delete() { IProductDao productDao = new ProductDaoImpl(); productDao.delete(24L); } @org.junit.Testpublic void queryById() { IProductDao productDao = new ProductDaoImpl(); Product product = productDao.queryById(31L); System.out.println(product); } @org.junit.Testpublic void queryAll() { IProductDao productDao = new ProductDaoImpl(); Listlist = productDao.queryAll();for (Product product: list) { System.out.println(product); } } }
3. MyBatis配置使用细节 3.1. 添加insert时拿到返回的主键
对应在XXXMapper.xml中需要做如下配置:
添加时拿到返回的主键: parameterType:需要传入的对象 useGeneratedKeys:是否需要主键 keyColumn:数据库中对应主键的列 keyProperty:对象中主键对应的id--><insert id="insert" parameterType="cn.yif.mybatis.domain.Product" useGeneratedKeys="true"keyColumn="id" keyProperty="id">insert into Product(productName, dir_id, salePrice, supplier, brand, cutoff, costPrice) values (#{productName}, #{dir_id}, #{salePrice}, #{supplier}, #{brand}, #{cutoff}, #{costPrice})insert>
3.2. Log4j日志配置
Log4j是MyBatis提供的日志打印依赖jar包,可以帮助我们进行分析和定位问题。在Log4j日志配置文件中我们可以规定日志打印显示的级别:
日志等级:从低到高(大小写没有关系,但是在配置的时候都建议使用大写)
等级从低到高(大小写没有关系,但是在配置的时候建议都写大写)TRACE:详细 (建议开发的时候用) DEDUG:调试,类似于System.out.print INFO:信息,类似于JPA打印sql等级 WARN:警告,程序可以正常运行,出现提示 ERROR:错误,出现异常 (建议正式环境)
具体配置文件应命名为log4j.properties,配置如下:
log4j.properties:
#log4j.properties(日志文件): #全局配置:先配置一个日志的根,这个级别是ERROR log4j.rootLogger=ERROR, stdout #局部配置 :把左边包名改成你自己的包名:表示我们自己这个路径下的代码级别 #级别说明:TRACE(详细)、Debug(调试)、Info(信息)、Warn(警告)、Error(错误) log4j.logger.cn.yif.mybatis=TRACE #在控制台输出和输出的格式 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
3.3.MyBatis中设置类的别名typeAliases
① MyBatis的内置别名
MyBatis中包含内置别名,即无需配置,MyBatis框架自动涵盖的别名,可以直接使用。
具体包含如下别名类型:
② 自定义别名
具体配置及其使用:
别名需要在mybatis-config.xml中使用,位置在
别名的配置,类的全限定名可以使用别名 alias:别名名称 type:别名所对应的类的全限定名,别名的使用与大小写无关--><typeAliases><typeAlias alias="Product" type="cn.yif.mybatis.domain.Product">typeAlias> <typeAlias alias="User" type="cn.yif.mybatis.domain.User">typeAlias>typeAliases>
使用别名:
在XXXMapper.xml文件中对应的类全限定名即可使用别名,且与大小写无关。
3.4.列名与属性名不一致ResultMap
数据库中的列名与Domain类中的属性名不一致时,如果直接使用ResultType对应,执行Sql查询语句等会出现相应值为null的情况,这时需要配置ResultMap进行关系映射对应,告诉Sql这个数据库中的列是对应Domain类中的哪个属性,具体配置如下:
<?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"> namespace:用来找唯一的mapper文件,一般是domain的全路径名+Mapper来命名 --><mapper namespace="cn.yif.mybatis.domain.User"> 当Domain中的属性与数据库中的字段列不一致时,需要使用resultMap id表示唯一标识,对应select中的resultMap type表示返回值类型 column:对应数据库中的列名 property:对应Domain中类的属性字段--> <resultMap id="userMap" type="User"> <result column="username" property="name">result> <result column="password" property="pwd">result> resultMap> id表示唯一标识,parameterType标识参数的类型,resultType表示返回值的类型--> <select id="getUserById" parameterType="Integer" resultMap="userMap">select * from user where id = #{id} select>mapper>
Copyright © 2004-2024 Ynicp.com 版权所有 法律顾问:建纬(昆明)律师事务所 昆明市网翼通科技有限公司 滇ICP备08002592号-4